关闭

剑指offer----链表中环的入口节点----java实现

标签: 链表中环的入口节点快慢指针链表剑指offerJava
260人阅读 评论(0) 收藏 举报
分类:

http://blog.csdn.net/snow_7/article/details/52181049


一个链表中包含环,请找出该链表的环的入口结点。

此问题包含两个步骤:

(1)判断链表中是否有环

(2)找出环

一、

1)选择快慢指针,让快指针每次走两步,慢指针每次走一步,若是单链表中有环的话,那么两个指针会相遇,即指向的相同的节点的值相等来判断。

2)当相遇的时候,慢指针在环中走了k步,设环之外的部分长为x,环的长度为n,则快指针一共走了 x+m*n步,(m为快指针在环中走的圈数),慢指针一共走了x+k步,因为快指针的速度是慢指针的两倍。那么可以得到2(x+k)=x+m*n+k;得到x为m*n-k ,慢指针在圈中还剩下的步数n-k;

二、

让快指针从头开始,两个指针每次都走一步,当快指针走了想x(m*n-k)步的时候,到达环的入口,慢指针在圈中走m-1圈加k步的时候,也到达环入口那个节点,两个指针再次相遇,此刻的节点就是环的入口的节点。


[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. /* 
  2.  public class ListNode { 
  3.     int val; 
  4.     ListNode next = null; 
  5.  
  6.     ListNode(int val) { 
  7.         this.val = val; 
  8.     } 
  9. } 
  10. */  
  11. public class Solution   
  12. {  
  13.   
  14.     public ListNode EntryNodeOfLoop(ListNode pHead)  
  15.     {  
  16.         if(pHead == null || pHead.next == null)  
  17.            return null;  
  18.        ListNode fast = pHead;//快指针每次走两步  
  19.        ListNode slow = pHead;//每次走一步  
  20.        while(fast!=null && fast.next !=null)//因为fast每次要走两步,所有需要判断fast的下一个是否为空  
  21.        {  
  22.            slow = slow.next;  
  23.            fast = fast.next.next;  
  24.            //判断是否相遇 相遇后让快指针从头开始走,每次都是走一步,第二次相遇的节点就是环的入口  
  25.            if(fast.val == slow.val)  
  26.            {  
  27.               fast = pHead;  
  28.               while(fast.val != slow.val)  
  29.               {  
  30.                   fast = fast.next;  
  31.                   slow = slow.next;  
  32.               }  
  33.            }  
  34.            if(fast.val == slow.val)  
  35.            {  
  36.                return slow;  
  37.            }  
  38.        }  
  39.        return null;//要是没有相遇,此链表没有环返回空  
  40.     }  
  41. }  


这类问题还可以延伸出来求

(1)环的长度、(2)整个链表的长度、(3)两个无环链表第一次相交的公共节点

(1)环的长度,当快慢指针第一次相遇的时候,把该节点保存下来,让慢指针接着走,当再次到达刚才相遇的节点时所走过的步数就是环的长度。

(2)利用第二步求出环以外的长度再加上环的长度,就是整个链表的长度

(3)先分别求出两个链表的长度,让长的链表先走两个链表长度差的步数,再让两个链表一起走,当走到节点值相同的那个节点时,就是相交的第一个公共节点。



/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        if (head == null || head.next == null) {
            return null;
        }
        ListNode slow = head;
        ListNode fast = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) {
                fast = head;
                while (slow != fast) {
                    slow = slow.next;
                    fast = fast.next;
                }
                if (slow == fast) {
                    return slow;
                }
            }
        }
        return null;
    }
}




0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:76236次
    • 积分:2009
    • 等级:
    • 排名:千里之外
    • 原创:121篇
    • 转载:56篇
    • 译文:0篇
    • 评论:7条
    最新评论