今天抽空做了几题,突然发现下面的题都过去很久了,发现这两天更新了两个链表,就写这两个链表吧。
题目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就是我们要找的结点。于是算法也就简单很多了。大家可以比较这种思路吧,也算很巧妙的解法。
这些问题都是自己的想法,肯定会有些漏洞,也可能有很多想不到的解法,请大家多多指正。