查看: 2525| 回复: 6
跳转到指定楼层
上一主题 下一主题
收起左侧

[树/链表/图] 链表五大必会--第一篇 适合新手

 
全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
特别感谢我的刷题小伙伴,昨晚不厌其烦的讲解和指导!感谢~

这篇帖子算是自己的刷题笔记,写在地里分享给有需要的小伙伴。

问:什么是链表五大须会类别
答: 1. 单链表翻转题目  Leetcode 206, 92, 234
        2. 链表中环的检测  Leetcode 141, 142
        3. 两个有序链表的合并  Leetcode 160, 21, 23
        4. 删除链表倒数第n个节点
        5. 求链表的中间节点

在写链表的问题时注意内容:
a. 链表是否为空
b. 链表操作头或者尾是否能成功
(如果a, b同时存在,可实用一个哨兵节点dummy 来简化我们的程序)
c. 链表只有一个
d. 链表只有两个

关于哨兵节点:
主要是用于操作头节点和尾结点,统一处理
  • 例如插入的时候 会有两种情况 list 为空 list不为空
  • 例如删除的时候 会有两种情况 该节点不是最后节点,该节点是最后节点。

我们使用哨兵节点可以将其归并处理

关于链表的赋值连接的技巧
例如删除时  我们要先找到 cur.pre 和 后一位的关系 (类似于先找到小三,并且确立关系,在甩掉现任) 先找后一位在处理当前节点的过程,可以保证我们不会有遗漏或者溢出。

正片开始
第一类
单链表翻转题目。
看了个课程,某时间app里面的数据结构于算法。讲课人据说自己是google 前工程师,出席过上百场的面试。作为面试官的他说,每次出链表翻转,百分之八十多的面试者都写不出来。(反正我是不太信,随机在地里抓十个人,应该过半的人都能写出来206这题)

206 Reverse Linked List 题目要求就是翻转整个字符串。
我这里提供两个思路。
思路1 是可以解决关于从头到尾这样类似的问题的模板
代码如下
class Solution {
    public ListNode reverseList(ListNode head) {
        //record the final ans
        ListNode pre = null;
        //cur list
        ListNode cur = head;
        while(cur != null){
            ListNode next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
}
具体图片如下所示


思路2 可以嵌套使用到 92 Reverse Linked List 2 当中 (平滑转移,丝滑享受)

代码如下
class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode dummy = new ListNode();
        dummy.next = head;

//先计算有多少个翻转的数
        int count = 0;
        while(head != null){
            count ++;
            head = head.next;
        }

        ListNode pre = dummy;
        ListNode cur = pre.next;
//从1开始的原因是 翻转次数 =  翻转数 - 1
        for(int i = 1; i < count; i++){
            ListNode temp = cur.next;
            cur.next = temp.next;
            temp.next = pre.next;
            pre.next = temp;
        }
        return dummy.next;
    }
}

详情请看下图





Leetcode 92
中间一段翻转
这个题就能看出 单链表相比于双链表的劣势了。因为他无法储存前一位,所以我们需要先跑到翻转前一位记录一下。然后后面翻转n次

代码就很简单,沿用206 第二种思路来写就好

代码如下
class Solution {
    public ListNode reverseBetween(ListNode head, int left, int right) {
        ListNode dummy = new ListNode();
        dummy.next = head;


        ListNode pre = dummy;
        for(int i = 0; i < left - 1; i++){
            pre = pre.next;
        }
        ListNode cur = pre.next;
        for(int i = left; i < right; i++){
            ListNode temp = cur.next;
            cur.next = temp.next;
            temp.next = pre.next;
            pre.next = temp;
        }
        return dummy.next;
    }
}

接下来是 234 Palindrom Linked List
这道题就是看是否是一个回文的linked list

思路:用快慢指针,快指针跑两位。翻转慢指针。比较快慢指针里的数 如果是不相同 那就gg

代码很简单

但是有个地方,卡了很久,最后在刷题小伙伴的帮助下想通的

Test Case [1,2,3,4,5]

class Solution {
    public boolean isPalindrome(ListNode head) {
        ListNode fast = head, slow = head;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
        }
        fast = head;
//在没跑 helper function时候  fast  【1,2,3,4,5】
        slow = helper(slow);
//跑完 helper function 之后 fast 【1,2,3】 我当时在想我的 4 5 被谁吃了!!! (原因请看 后面图片)
        while(slow != null){
            if(slow.val != fast.val) return false;
            slow = slow.next;
            fast = fast.next;
        }
        return true;
    }
//翻转function
    public ListNode helper(ListNode shead){
        ListNode dummy = new ListNode();
        dummy.next = shead;
        int count = 0;
        while(shead != null){
            count ++;
            shead = shead.next;
        }
        ListNode pre = dummy;
        ListNode cur = pre.next;
        for(int i = 1; i < count; i++){
            ListNode temp = cur.next;
            cur.next = temp.next;
            temp.next = pre.next;
            pre.next = temp;
        }
        return dummy.next;
    }
}

原因是因为,我翻转3 4 5 ->null  导致了 我的fast 里面的链表断开了 从 1 2 3 -》 4 5 短开成 1 2 3-》null 了



突然发现码字比写码还费劲。关于第二条和第三天稍后更新。实在是累了

其实里面还有个问题也是想了很久,建议新手也要去了解一下 pass by reference  和 pass by value 的区别










补充内容 (2021-11-07 13:34 +8:00):
链表三部曲的第二篇  传送门  https://www.1point3acres.com/bbs/thread-816987-1-1.html

补充内容 (2021-11-09 23:08 +8:00):
最后两个必会类型实在是没什么好讲的大概看看就能明白  我更新一下题号把。如果任何人需要看代码的话,请在下方留言我会更新一片代码贴

4. 删除链表倒数第n个节点
            leetcode 237 103 19
5. 求链表的中间节点
            leetcode 876

顺便更新两道题到第一个类型
1. 单链表翻转题目  增加 24, 25两题

补充内容 (2021-11-19 01:49 +8:00):
更新一下题号
1. 单链表翻转题目  Leetcode 206, 92, 234, 25, 24
2. 链表中环的检测  Leetcode 141, 142
 3. 两个有序链表的合并和插入  Leetcode 160, 21, 23, 328, 2, 86, 445
 4. 删除链表倒数第n个节点LeetCode 82 83 237 203 19
 5. 求链表的中间节点leetcode 876
6. LRU 146
7. 扩展了解 138 148

评分

参与人数 11大米 +11 收起 理由
fireonice7 + 1 赞一个
jimmyjohn315 + 1 很有用的信息!
Ben_Zz + 1 给你点个赞!
In江湖 + 1 赞一个
lulu3331 + 1 给你点个赞!

查看全部评分


上一篇:有没有一起刷题的小伙伴啊啊啊啊
下一篇:我把几大热门语言都学完了但是还是看不懂算法和数据结构题我该怎么办?
全局:
额 文科生表示看到标题以为是楼主在讲七日链十日链腕表品牌挑选。我还是太嫩了
回复

使用道具 举报

全局:
mark链表
回复

使用道具 举报

🔗
vvqqdd 2021-11-6 12:12:43 | 只看该作者
全局:
代码用论坛自带的那个排版下
回复

使用道具 举报

🔗
fsab9 2021-11-6 23:19:15 来自APP | 只看该作者
全局:
总结得很棒 谢谢分享
回复

使用道具 举报

🔗
Vanda 2021-11-7 05:51:00 来自APP | 只看该作者
全局:
很棒谢谢分享!
回复

使用道具 举报

全局:
马克链表。谢谢lz
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表