0
点赞
收藏
分享

微信扫一扫

考研入门55问---基础知识篇

余寿 2024-05-05 阅读 13

(题目来源:力扣)

一.判读一个链表是否是环形链表

题目: 

解答:

方法:快慢指针法 

内容:分别定义快慢指针(fast和slow),快指针一次走两步,慢指针一次走一步。

原理:若不成环,则快指针(或快指针的next)一定会走到空,据此,写出循环条件,当循环结束时,返回NULL

while(fast&&fast->next)

此时,问题来了,成环怎么办?不能再通过循环条件来判断(因为此时该循环是死循环了)

目光再回到快慢指针上,若成环,则快指针一定会有追上慢指针的时候,当它们相遇时,循环结束

证明:

 解题代码(并非完整代码)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool hasCycle(struct ListNode *head) 
{
    struct ListNode* fast = head;
    struct ListNode* slow = head;
    while(fast && fast->next)
    {
        fast = fast->next->next;
        slow = slow->next;
        if(fast == slow)
        {
            return true;
        }
    }
    return false; 
}

拓展:

 总结:当N为奇数,C为偶数时,二者一直错过,无法相遇

真的是这样吗?

C是偶数且N是奇数,这个条件能同时满足吗?

不妨推导一下: 

(fast走n步的情况就交给读者自行思考了)

二.找到环形链表开始进入环的第一个节点

题目: 

解答:

设进入环的第一个节点为 ptail

1.先判断是否是环形链表(同上)

2.找到开始进入环的第一个节点

方法:

先定义快慢指针:fast和slow,fast一次走两步,slow一次走一步

先让fast和slow相遇,定义meet指针指向相遇节点

定义一个新指针newhead 指向链表的头结点,然后让newhead和meet指针同时向前走,他们相遇的节点就是ptail

证明:

解题代码(非完整代码)

struct ListNode *detectCycle(struct ListNode *head) 
{
    //先判断有无环,并找到相遇时的节点
    struct ListNode* fast = head;
    struct ListNode* slow = head;
    struct ListNode* meet = NULL;
    while(fast && fast->next)
    {
        fast = fast->next->next;
        slow = slow->next;
        //相遇
        if(fast == slow)
        {
            meet = fast;
            struct ListNode* newhead = head;
            while(newhead != meet)
            {
            newhead = newhead->next;
            meet = meet->next;
            }
            return meet;
        }
    }
    return NULL;
}
举报

相关推荐

0 条评论