(LeetCode 141/142)Linked List Cycle

1、Given a linked list, determine if it has a cycle in it.

2、Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

3、Given a linked list, return the length of the cycle, if there is no cycle, return 0;

题目要求:

1、给一个链表,判断它是否存在环;

2、给一个链表,如果它存在环,请返回环的起点,否则,返回NULL;

3、给一个链表,如果它存在环,请返回环的长度,否则,返回0;

解题思路:

1、判断是否存在环?

方法1:增加一个set容器,遍历链表,将各个结点依次加入Set集合中,如果该节点已存在集合中,说明存在环;如果遍历结束后,发现没有重复的结点,则说明没有环。

方法2:无需额外空间,设置两个指针p1,p2,从头结点开始,一个走一步,p1=p1->next;,一个走两步,p2=p2->next->next,如果存在环,那么两个指针肯定会相遇;如果走得快的指针p2到达了终点,说明没有环。

2、如何求环的起点和环的长度呢?

设链表起点距离环的起点距离为a,圈长为n,当p1和p2相遇时,相遇点距离环起点距离为b,此时b已绕环走了k圈,则

p1走的距离为a+b;

p2速度为p1的两倍,p2走的距离为2*(a+b);

p2走的距离为a+b+k*n=2*(a+b),从而a+b=k*n

即当p1走a步,p2走(k*n-b)步,当k=1时,则为(n-b)步;

因此如何求环的起点?把p1拉回起点重新出发,p2从相遇点继续走,p1,p2每次均走一步,a步后,p1到达起点,p2也刚好到圈的起点。

如何求环的长度?相遇后,p2再走一圈并统计长度就是圈长。

参考代码:

1、判断是否存在环?

/**
 * 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) {
       set<ListNode*> psets;
       for(ListNode *p=head;p!=NULL;p=p->next){
           if(psets.find(p)!=psets.end())
                return true;
           psets.insert(p);
       }
       return false;
    }
};
/**
 * 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==NULL || head->next==NULL)
//            return false;
        ListNode *p1=head;
        ListNode *p2=head;
        while(p2 && p2->next){
            p1=p1->next;
            p2=p2->next->next;
            if(p1==p2)
                return true;
        }
        return false;
    }
};

2、求环的起点

/**
 * 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 *p1,*p2;
        p1=head;
        p2=head;
        while(p2 && p2->next){
            p1=p1->next;
            p2=p2->next->next;
            if(p1==p2){
                // p1 points back to head,p2 still stand where they have met
                // p1,p2 take the same steps
                // when they meet again, that‘s where the cycle starts
                p1=head;
                while(p1!=p2){
                    p1=p1->next;
                    p2=p2->next;
                }
                return p1;
            }
        }
        return NULL;
    }
};

3、求环的长度

/**
 * 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 *p1,*p2;
        p1=head;
        p2=head;
        while(p2 && p2->next){
            p1=p1->next;
            p2=p2->next->next;
            if(p1==p2){
                // if p2 cycles around,then the length of cycle can be counted
                ListNode *p=p2->next;
                int length=1;
                while(p!=p2){
                    length++;
                    p2=p2->next;
                }
                return length;
            }
        }
        return 0;
    }
};
时间: 2024-08-09 23:39:36

(LeetCode 141/142)Linked List Cycle的相关文章

LeetCode 142 链表 Linked List Cycle II

LeetCode 142 链表 Linked List Cycle II LeetCode Given a linked list, return the node where the cycle begins. If there is no cycle, return null. To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexe

LeetCode之“链表”:Linked List Cycle &amp;&amp; Linked List Cycle II

1. Linked List Cycle 题目链接 题目要求: Given a linked list, determine if it has a cycle in it. Follow up: Can you solve it without using extra space? 刚看到这道题,很容易写出下边的程序: 1 bool hasCycle(ListNode *head) { 2 ListNode *a = head, *b = head; 3 while(a) 4 { 5 b =

leetcode day5 -- Reorder List &amp;&amp; Linked List Cycle II

1.  Reorder List Given a singly linked list L: L0→L1→-→Ln-1→Ln, reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→- You must do this in-place without altering the nodes' values. For example, Given {1,2,3,4}, reorder it to {1,4,2,3}. 分析:翻转链表是很常见的题目,这种翻转是第一次见.一开始

141. 环形链表(Linked List Cycle)

目录 题目描述: 示例 1: 示例 2: 示例 3: 进阶: 解法: 题目描述: 给定一个链表,判断链表中是否有环. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 pos 是 -1,则在该链表中没有环. 示例 1: 输入:head = [3,2,0,-4], pos = 1 输出:true 解释:链表中有一个环,其尾部连接到第二个节点. 示例 2: 输入:head = [1,2], pos = 0 输出:true 解释:链表中有一个环,

LeetCode 141, 142. Linked List Cycle I+II

判断链表有没有环,用Floyd Cycle Detection算法,用两个快慢指针. class Solution { public: bool hasCycle(ListNode *head) { if (!head) return false; ListNode *slow, *fast; slow=fast=head; do{ if (fast==NULL || fast->next==NULL) return false; slow = slow->next; fast = fast-

leetcode 141 142. Linked List Cycle

题目描述: 不用辅助空间判断,链表中是否有环 /** * 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 ==

leetcode || 142、Linked List Cycle II

problem: Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Follow up: Can you solve it without using extra space? Hide Tags Linked List Two Pointers 题意:如果一个单链表存在环形结构,返回环的起点.空间复杂度满足O(1) thinking: (1)上一题使用快

LeetCode刷题:Linked List Cycle 及其进阶Linked List Cycle II

Given a linked list, determine if it has a cycle in it. Follow up: Can you solve it without using extra space? 1. 首先解决的问题是 判断单链表 有没有环? 解题思路: 两个指针slow 和 fast,开始都指向 head, slow指针每次走一步,fast 指针每次走两步,看看最终 slow 和 fast 会不会重合,如果 链表有环,那么一定会重合. /** * Definition

已知前序(后序)遍历序列和中序遍历序列构建二叉树(Leetcode相关题目)

1.文字描述: 已知一颗二叉树的前序(后序)遍历序列和中序遍历序列,如何构建这棵二叉树? 以前序为例子: 前序遍历序列:ABCDEF 中序遍历序列:CBDAEF 前序遍历先访问根节点,因此前序遍历序列的第一个字母肯定就是根节点,即A是根节点:然后,由于中序遍历先访问左子树,再访问根节点,最后访问右子树,所以我们找到中序遍历中A的位置,然后A左边的字母就是左子树了,也就是CBD是根节点的左子树:同样的,得到EF为根节点的右子树. 将前序遍历序列分成BCD和EF,分别对左子树和右子树应用同样的方法,