LeetCode || Linked List Cycle 1&2

Linked List Cycle

  Total Accepted: 14505  Total Submissions: 41837 My 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: 33540 My 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;
    }
};









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值