IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【典例】 链表经典列题@链表 -> 正文阅读

[数据结构与算法]【典例】 链表经典列题@链表

相信大家再初学数据结构时也会和我遇到相同的情形遇到题目无法构成有效的思路。

通过不断地练习题目我相信我们也会变成大佬的 ,也会拿到大厂offer。😀


链表排序

首先我们根据题目了解到这题解题思路 大概会用到 ①?双指针链表排序?

1.设置fast和slow两个指针利用fast走两步slow走一步的原理将slow置为链表的中间节点,而此时pre指针指向slow指针前一个结点。所以现在将pre指针置为null,就可以将原有链表分为两部分。

2.将两部分链表进行排序。以便完成下一步动作。

3.到这一步 两部分链表皆以排好序,创建新的节点头 比较两个链表头节点的值,使用新链表结点与值小的一方连接。

4.完成全部步骤 只需返回设置的结点即可。

class Solution {
    public ListNode sortList(ListNode head) {
       return mergeSort(head); }
    ListNode mergeSort(ListNode head){
        if(head == null || head.next == null) return head;
        ListNode fast = head;
        ListNode slow = head;
        ListNode pre = null;
        while(fast != null && fast.next != null){//使用快慢指针找出链表中间位置结点
            pre = slow;//此时pre 在last前一个位置上
            fast = fast.next.next;
                slow = slow.next;
          }
           pre.next = null;//使得pre的next为空 这样链表就分为两部分 一部分以head开头 一部分以slow开头
         ListNode l1 =  mergeSort(head);使用归并排序进行对链表两部分进行排序
         ListNode l2 =  mergeSort(slow);
         return  merge(l1, l2);
        }
      ListNode merge(ListNode l1, ListNode l2){
        ListNode newhead = new ListNode(0);创建新的链表头
        ListNode cur3 = newhead;
      while(l1 != null && l2 != null){
         if(l1.val < l2.val){比较两个链表的值谁小
             cur3.next = l1;用cur3 接上
             l1 = l1.next;
             }else{
             cur3.next = l2;
             l2 = l2.next;
            }
            cur3 = cur3.next;
          }
          if(l1 != null){
              cur3.next = l1;
          }
          if(l2 != null){
              cur3.next = l2;
          }
          return newhead.next;
    }
}

删除排序链表中的重复元素?

??

解题思路

和往常解题思路一样先判断特殊情况

创建新的节点连接头节点 此时利用l2来判决? 看 l2.val值和 l2.next.val是否相同。

这一步给大家介绍

当我们进入if循环里时 就代表 l2.val == l2.next.val 当我们while走完? ?就代表当前值和下一个值不同

此时呢我们还在 if 里面 为了防止紧跟这的还是一组相同的值 我们需要在循环里持续这一句持续判断。

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head == null || head.next == null) return head;
      ListNode newhere = new ListNode (0);创建新的节点
      newhere.next = head;
      ListNode l1 = newhere;
      ListNode l2 = head;
   while(l2 != null){循环条件 l2不能为空
      if(l2.next != null && l2.val == l2.next.val){此时判断l2 的val 和l2.next的val是否相同
            while(l2.next != null && l2.val == l2.next.val){这一步是至关重要的 会在解题思路中讲清
                l2 = l2.next;
            }
            l1.next = l2.next;
            l2 = l1.next;
          }else{
              l1 = l2;
              l2 = l2.next;
          }
      }
      
       return newhere.next;
     
    }
}

?重排链表

?

??

了解题意 是要将第一个和最后一个连接 第二个和倒数第二个相连 依次往后 直到最中间元素位置为止

使用快慢指针进行操作 找到中间元素 分为两个链表部分 将后半部分进行逆置 使最后一个元素变为第一个元素然后进行合并。

class Solution {
    public void reorderList(ListNode head) {
    ListNode fast = head.next;
    ListNode slow = head;
    while(fast != null && fast.next != null){快慢指针进行操作
        fast = fast.next.next;
        slow = slow.next;
    }
    ListNode pre = slow.next;
    ListNode cur1 = null;
    slow.next = null;
    while(pre != null){反转链表操作
    ListNode cur =  pre.next;
    pre.next = cur1;
    cur1 = pre;
    pre = cur;
 }
 ListNode cur3 = head;
  ListNode l3 = cur1;
   while(cur3 != null && l3 != null){
       ListNode l1 = cur3.next;将两个链表合并
       ListNode l2 = l3.next;
        cur3.next = l3;
        cur3 = l1;
          l3.next = cur3;
        l3 = l2;


   }
    }
}

?从链表中删除总和值为零的连续节点

?

解题思路

持续遍历结点并将其和加在一起 进行判断为零时进行操作。

class Solution {
    public ListNode removeZeroSumSublists(ListNode head) {
       ListNode pre = new ListNode(0);
       ListNode cur =pre;
       pre.next = head;
      while(pre != null){
           ListNode cur1 = pre.next;
           int sum = 0;
           while(cur1 != null){计算和值为零时
               sum += cur1.val;
               cur1 = cur1.next;
               if(sum == 0){当寻找到所需时
                   pre.next = cur1;进行删除
                   break;
               }
           }
           if(cur1 == null) pre = pre.next;
      
      }
       return cur.next;
    }
}

?反转链表

当我们看到这题时会想到我们应该先找到right 后面一个结点和 left 前一个结点。这样方便我们进行逆置。事实也是如此?

class Solution {
    public ListNode reverseBetween(ListNode head, int left, int right) {
     ListNode node = new ListNode(0);
     node.next = head;
     ListNode pre = node;
     for(int i = 1; i < left; i ++){先找到left前一个结点
         pre = pre.next;

     }
     ListNode haed = pre.next;将haed插入要逆置的第一元素
     for(int j = left; j < right; j ++  ){下面这部分进行逆置
         ListNode nex = haed.next;
         haed.next = nex.next;
         nex.next = pre.next;
         pre.next = nex;
     }
     return node.next;
    }最后输出头结点
}

相信明天更好!!!🤭

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-02-16 13:22:22  更:2022-02-16 13:22:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 17:38:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码