LeetCode || Linked List Cycle 1&2

来源:互联网 发布:java的输入流和输出流 编辑:程序博客网 时间:2024/05/24 00:11

Linked List Cycle

 Total Accepted: 14505 Total Submissions: 41837My Submissions

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

Follow up:
Can you solve it without using extra space?


思路:开始时,我最初的思路是利用ListNode中的val变量来当做标志变量,每当访问过一个节点之后就令 val=-1,继续往下,如果遇到val=-1 的节点,就认为是重复访问了,但是明显这种方法是不合理的,因为我们不能改变链表,也不能改变链表节点的val值。
        后来在Discuss中看到了有人说用 fast runner slow runner 方法,就是利用两个指针变量slow和fast,slow一次走一步,fast一次走两步,显然如果链表存在环,那么fast一定会“追上”slow,判断是直接用这两个指针  slow==fast。
/** * 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) {        ListNode *fast=head;        ListNode *slow=head;        while(slow!=NULL&&fast!=NULL&&fast->next!=NULL){            slow=slow->next;            fast=fast->next->next;            if(slow==fast)                return true;        }        return false;    }};
注意 NULL->next  不允许出现。

Linked List Cycle II

 Total Accepted: 10250 Total Submissions: 33540My Submissions

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?


解法一:首先不考虑空间使用量,那么可以用一个map来存储当前遍历过的指针,一旦遇到第一个重复的,那么直接返回即可。代码如下:

class Solution {public:    ListNode *detectCycle(ListNode *head) {        map<ListNode*, int> mp;        ListNode *pone=head, *ptwo;        while(pone){            if(mp.count(pone))                return pone;            mp.insert(pair<ListNode*, int>(pone, 1));            pone=pone->next;        }        return NULL;    }};

解法二:但是题目说了,本题可以用O(1)空间来解,方法很难想到,思路是同样适用两个指针遍历,一个快(p一次走两步),一个慢(q一次走一步),二者会在环中某个节点相遇,相遇时二者走过的路程相差一倍,我们设环形开始的节点为s,s距离head为x,相遇节点m距离s为y,环形长度为l,那么二者走过的路程分别为:
        P=x+k*l+y
        Q=x+m*l+y
    且 P=2*Q,故可以推出:k*l=2*m*l+x+y,即 x+y 是 l 的整数倍,而p现在在环形的m处,m距离s为y,故p再走x步就能再次到达 s ,也即我们要找的节点处。所以再让 p 走x步就行了,而这个x的计步方法就是再让一个指针从 head出发,与p同时走,相遇时就到s了。

class Solution {public:    ListNode *detectCycle(ListNode *head) {        map<ListNode*, int> mp;        ListNode *pone=head, *ptwo=head;        while(pone&&ptwo){            pone=pone->next;            if(ptwo->next)                ptwo=ptwo->next->next;            else                return NULL;            if(pone==ptwo)                break;        }        if(!pone||!ptwo)            return NULL;        pone=head;        while(pone!=ptwo){            pone=pone->next;            ptwo=ptwo->next;        }        return pone;    }};









0 0
原创粉丝点击