• 面试题 02.08. 环路检测(返回环路开头节点)


    面试题 02.08. 环路检测

    给定一个链表,如果它是有环链表,实现一个算法返回环路的开头节点。
    有环链表的定义:在链表中某个节点的next元素指向在它前面出现过的节点,则表明该链表存在环路。

    示例 1:

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

    示例 2:

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

    示例 3:

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

    进阶:
    你是否可以不用额外空间解决此题?

    思路一 利用哈希表

    /**
     * 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) {
            if(head == NULL || head->next ==NULL)
                return NULL;
            unordered_set<ListNode*> seen;
            while(head!=NULL)
            {
                if(seen.count(head))
                    return head;
                seen.insert(head);
                head = head->next;
            }
            return NULL;
        }
    };
    

    思路二 利用快慢指针(数学问题)

    //如果链表有环,请找到环的入口点
    //fast一次走两步,slow一次走一步。所以,相遇的时候,fast所走的路程是slow所走的路程的两倍
    //设起始位置到环入口点的距离为X,入口点到第一次相遇的位置的距离为L,C代表环的长度。
    //slow和fast第一次相遇时,slow:X+L;   fast:X+L+NC (N指代圈次)。
    // 由上推出:  2(X+L) = X+L+NC  ->  X = NC - L;和圈数(环数)无关  -> X = C - L;
    // 由上可得:当slow和fast第一次相遇时,把slow放到链表头部,与fast一起走,直到再次相遇,
    // 那么这个相遇点就是环的入口点。
    
    public class Solution {
        public ListNode detectCycle(ListNode head) {
            ListNode fast = head;
            ListNode slow = head;
        
            while (fast != null && fast.next != null) {
                slow = slow.next;
                fast = fast.next.next;
                if (fast == slow) {
                    while (fast != head) {
                        fast = fast.next;
                        head = head.next;
                    }
                    return head;//改善在此处
                }
            }
            return null;
        }
    }
    

    链接

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/linked-list-cycle-lcci

  • 相关阅读:
    Windows XP中万能断点
    c#运算符 ?
    转神秘的程序员
    经典解决“线程间操作无效
    文件上传
    dowload.aspx
    mail
    js 正则
    新年快乐
    DataTable Compute
  • 原文地址:https://www.cnblogs.com/jiashun/p/LeetCode_0208.html
Copyright © 2020-2023  润新知