您的位置:首页 > 其它

如何判断单链表中是否有环?如何找到环中的起始节点

2014-06-16 21:42 696 查看
今天在leetcode上做了一道题:

Given a linked list, return the node where the cycle begins. If there is no cycle, return
null


假设给定的例子如下:




下面给出解决思路:

(1)首先需要判断该链表是否存在环:设置两个指针,一个慢指针,一个快指针。慢指针每次走一步,快指针每次走两步。如果快慢指针最后相遇了则说明该链表有环,否则没有环。

/*

*@param head

*@return the node which they meet each other

*/

private ListNode CycleNode(ListNode head){
if(head == null || head.next == null){
return null;
}
ListNode slow = head;
ListNode fast = slow.next;
while(slow != fast){
if(fast.next != null && fast.next.next != null){
fast = fast.next.next;
}else{
return null;
}
if(slow.next != null){
slow = slow.next;
}else{
return null;
}
}
return slow;
}


(2)接下来就是找到环的起始节点:将相遇节点的前一个指针切断的话,这道题就是一道两个单链表如何判断相遇点的问题。



单链表判断相遇点的解决思路如下:

(1)计算链表1的长度为len1

(2)计算链表2的长度为len2

(3)比较len1和len2的大小,如果len1大,则先遍历链表1,遍历长度为len1-len2,此时两个链表再同时遍历,当指针指向同一个节点时,就为相遇节点,也就是环的第一个节点;如果len2大同理。

private ListNode firstCycle(ListNode cyclenode, ListNode head){
int lenhc = 1;
ListNode node1 = head;
while(node1.next != cyclenode){
node1 = node1.next;
lenhc++;
}
int lencc = 1;
ListNode node2 = cyclenode;
while(node2.next != cyclenode){
node2 = node2.next;
lencc++;
}
if(lenhc > lencc){
int diff = lenhc - lencc;
node1 = head;
while(diff != 0){
node1 = node1.next;
diff--;
}
node2 = cyclenode;
while(node1 != node2){
node1 = node1.next;
node2 = node2.next;
}
return node1;
}else{
int diff = lencc - lenhc;
node1 = cyclenode;
while(diff != 0){
node1 = node1.next;
diff--;
}
node2 = head;
while(node1 != node2){
node1 = node1.next;
node2 = node2.next;
}
return node1;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  单链表