leetcode Linked List Cycle I II

今天抽空做了几题,突然发现下面的题都过去很久了,发现这两天更新了两个链表,就写这两个链表吧。


题目1:

题目就是判断一个链表是否有环。。要求不增加额外空间。如果以前没有做过可能会卡,这个题因为我以前见过就直接写代码了,没有在本地测试,直接写上去了,两次ac。。。

解法的证明我就不多说了,大家搜搜吧。。定义两个指针pre,p每次一个走两步,一个走一步。如果链表有环的话,那么就会pre==p。如果走的过程中有NULL说明没有环,算法结束。直接代码吧

class Solution {
public:
    bool hasCycle(ListNode *head) {
        // IMPORTANT: Please reset any member data you declared, as
        // the same Solution instance will be reused for each test case.
        if(!head)
            return false;
        ListNode *pre,*p;
        pre=head;p=head->next;
        while(pre!=p)
       {
           if(p && p->next && p->next->next)
           {
               p=p->next->next;
           }
           else
                return false;
            if(pre->next)
                pre=pre->next;
           
       }
       return true;
    }
};

第一次写的时候没有判断p,当只有一个节点时会出错。代码比较简单就不多说了。


其实还想到一种方法,如果有环的话那么环最后一个结点的next会出现在最后一个结点之前,也可以每次去遍历结点,如果在遍历结点next之前都没有遍历到结点就说明这个结点在环内,如果没有环肯定不会遇到next之前,遍历到结点。

代码没有写,大家可以比较两个想法的差异吧。


题目2:

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?

好郁闷,刚写的一不小心给删除了。。。还得重新写。。。。郁闷。。。。。。


这个还是找环的问题,不同的是这次需要我们找到环的开始结点(如果有的话)。。。

第一题我们已经能够判断一个链表是否有环了,这次只需要找到起始结点就可以了。如何找到环呢??我们可以用到环的性质,什么性质呢,就是结点在一个环内,那么遍历这个环肯定会回到这个结点!!于是从head开始找开始结点,pre==p是环内的结点。控制p从pre开始遍历,同时定义一个指针target从head开始往后移动,p遍历一圈环如果遇到target返回target,如果没有遇到,target=target->next,如果有环肯定会遇到target。算法结束,时间复杂度应该是O(n*n).

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        // IMPORTANT: Please reset any member data you declared, as
        // the same Solution instance will be reused for each test case.
     if(!head)
        return NULL;
    if(head->next==head)
        return head;
    ListNode *pre,*p;
    pre=head;p=head->next;
    while(pre!=p)
    {
        if(p && p->next && p->next->next)
        {
            p=p->next->next;
        }
        else
            return NULL;
        if(pre->next)
            pre=pre->next;
    }
    if(p->next==p)
        return p;
    ListNode *target=head;
    while(1)
    {
        p=pre->next;
        while(p!=pre)
        {
            if(p==target)
                return target;
            p=p->next;
        }
        target=target->next;
    }
    return NULL;  
    }
};


没有在本地测试,直接在oj上面测试了两次bug交了3次。。晕。。。特殊情况就是末尾结点指向自己的时候。if(p==p->next)这个是个环,返回就可以了。


今天跟他们说这个问题的时候,突然发现上面说的第二种解法就是第二题。所以可以在判断有环的情况下,那么他的最后一个环结点的next就是我们要找的结点。于是算法也就简单很多了。大家可以比较这种思路吧,也算很巧妙的解法。


这些问题都是自己的想法,肯定会有些漏洞,也可能有很多想不到的解法,请大家多多指正。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值