Day5-leetcode876、141、142

今天的学习重点是快慢指针法求解关于环形链表的那些事

快慢指针法:

主要是指一个遍历链表的方法,我们通过fast和slow两个指针进行遍历链表。

我们规定为fast每次走两步,slow则每次走一步

以此的根据下对不同的题目进行不同的变动

876.链表的中间结点

(1)题目描述

题目链接如下:

力扣876. 链表的中间结点​icon-default.png?t=M85Bhttp://leetcode.cn/problems/middle-of-the-linked-list/description/

给定一个头结点为 head 的非空单链表,返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。

示例 1:

输入:[1,2,3,4,5]
输出:此列表中的结点 3 (序列化形式:[3,4,5])
返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。
注意,我们返回了一个 ListNode 类型的对象 ans,这样:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.

示例 2:

输入:[1,2,3,4,5,6]
输出:此列表中的结点 4 (序列化形式:[4,5,6])
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。

提示:

  • 给定链表的结点数介于 1 和 100 之间。

做题分析:

用自己的话解释题意:

把一个链表,找到链表最中间的节点。


开始思考解决方法:

这一题,因为恰巧我们是要寻找中间的节点

那么也刚好对应了我们的快慢指针的一个走法。

当我们fast指针走到末尾或者末尾的空指针时,slow指针就刚好处于中间节点。

只需要特判fast的状态即可。

代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* middleNode(ListNode* head) {
        ListNode *sl,*fa;
        sl=head;
        fa=head;
        while(fa!=NULL&&fa->next!=NULL){
            sl=sl->next;
            fa=fa->next->next;
        }
        return sl;
    }
};

141.环形链表

(1)题目描述

题目链接如下:

力扣141. 环形链表icon-default.png?t=M85Bhttps://leetcode.cn/problems/linked-list-cycle/description/

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

提示:

  • 链表中节点的数目范围是 [0, 104]
  • -105 <= Node.val <= 105
  • pos 为 -1 或者链表中的一个 有效索引 。

做题分析:

用自己的话解释题意:

把一个链表,判断是否有环。


开始思考解决方法:

这一题问题也是不大,因为只要有环的话,那么两个指针一定会陷入到环里,

那么处于最开始前面的fast指针一定会在环里和slow指针相遇。

那我们的循环遍历条件只要稍加改正即可。

具体代码实现:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        if(head==nullptr||head->next==nullptr)return false;
        ListNode *l,*f;
        l=head;
        f=head->next;
        while(l!=f){
            if(f==NULL||f->next==NULL)return false;
            l=l->next;
            f=f->next->next;
        }
        return true;
    }
};

142.环形链表 II

(1)题目描述

题目链接如下:

力扣142. 环形链表 II​icon-default.png?t=M85Bhttp://leetcode.cn/problems/linked-list-cycle-ii/description/

给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。

提示:

  • 链表中节点的数目范围在范围 [0, 104] 内
  • -105 <= Node.val <= 105
  • pos 的值为 -1 或者链表中的一个有效索引

做题分析:

用自己的话解释题意:

把一个链表,判断环的起点。


开始思考解决方法:

这题在写的过程中有着很大的问题。

刚开始以为就是一道平平无奇的快慢指针法。

但是左思右想都差点意思好像。

发现我们需要推论一些结论之后才能得出本题的方法

那么以下就是我通过看题解之后得出的结论

 

我们设置a为head到环入口的距离

b为环入口到fast和slow相遇的距离

c为环的剩余距离

那么我们可得出图片上的结论

那么接下来一个简单但又不简单的推导

我们a-c是不是相当于,把head节点往前走了c步

那么如果我们相遇的slow节点同时也运动c步是不是就到达了环的入口

那么接下来的(a-c)=(k-1)(b+c)

是不是就代表,head节点往前走了c步后,与环的入口剩余距离时环的整数倍。那么我们

因为slow此时也走了c步,那么接下来如果继续同步运动的话

head和slow相遇的地方就是环的入口。

 

我们代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode *sl,*fa;
        fa=head;
        sl=head;
        while(fa!=NULL&&fa->next!=NULL){
            fa=fa->next->next;
            sl=sl->next;
            if(fa==sl){
                while(head!=sl){
                    sl=sl->next;
                    head=head->next;

                }
                return head;
            }
        }return NULL;
    }
};

二、总结及计划

今天,第三道题完全给我搞不会了

心态直接写炸了

为啥还有这么多数学推导。

不过看了很久的讲解和不同的方法也算是理解了

文章里的思路和讲解引用这个视频里的环形链表的入口怎么找?一个视频讲透快慢指针!【基础算法精讲 07】链表的中间结点 | 环形链表II | 重排链表 | 力扣 LeetCode 高频面试题_哔哩哔哩_bilibili

早早睡觉了。

越是痛苦越是成长了,坚持打卡。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值