leetCode刷题归纳-linked list(141. Linked List Cycle&& Add to List 142. Linked List Cycle II)

这一题还蛮有意思的,虽然不太复杂,但是也是一种很简便的算法思想,所以在此做一下记录

题目描述: 141. Linked List Cycle I


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

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

Subscribe to see which companies asked this question.

解题思想


难点就在于不让消耗空间复杂度,这样怎么办?
我们可以模拟一个“赛跑”的过程:

/**
 * 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 ) return false;
        ListNode *walk=head,*run=head->next;
        while(run&&run->next&&run->next->next){//将run->next放在前面避免发生NULL->next的情况
            if(run==walk) return true;
            run=run->next->next;//run跳两步
            walk=walk->next;//walk只走一步
        } 
        return false;
    }
};

————————————————-我是分割线——————————————————


题目描述: 142. Linked List Cycle II

解题思想


难点就在于不让消耗空间复杂度,这样怎么办?
我们可以模拟一个“赛跑”的过程:
题目的要求改成了:
Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

现在的问题不是有没有环,而是环开始的位置在哪里,要求更高了,怎么办?

还是“赛跑”的方法,求出环的开始点的偏移量:

/**
 * 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 || !(head->next))  return NULL;
        ListNode *walk=head,*run=head;
        bool isCycle=false;
        while(run->next&&run->next->next){
            run=run->next->next;
            walk=walk->next;
            if(walk==run) {isCycle=true; break;}
        }
        if(!isCycle) return NULL;
        //这里非常重要!好好记住这个性质!!!
        walk=head;
        while(walk!=run){
            walk=walk->next; run=run->next; 
        }
        return walk;
    }
};

下面还有一种利用样例漏洞的办法,是一开始想出来的办法,比较起来有点low就一笔带过了。。。。需要解释的话可以留言。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值