单链表——求两个单链表相交的第一个节点

package jxau.lyx.link;

/**
 * 
 * @author: liyixiang
 * @data:2014-10-2
 * @题目大意:
 * 		求两个单链表相交的第一个节点
 * @主要思路:
 * 		 对第一个链表遍历,计算长度len1,同时保存最后一个节点的地址。        
 * 对第二个链表遍历,计算长度len2,同时检查最后一个节点是否和第一个链表的最后一个节点
 * 相同,若不相同,不相交,结束。        
 * 		两个链表均从头节点开始,假设len1大于len2,那么将第一个链表先遍历len1-len2个节点
 * 此时两个链表当前节点到第一个相交节点的距离就相等了,然后一起向后遍历,直到两个节点
 * 的地址相同。
 * @时间复杂度:
 * 		O(len1+len2)
 * 
 * 		   ----   len2        
 *                    |__________       
 *                    |            
 *  ---------   len1  
 *                           
 *     	  |---|<- len1-len2
 *                                 
 * @空间复杂度:
 */
public class GetFirstCommonNode {
	
	//结点
	private static class Node {           
		int val;           
		Node next;               
		
		public Node(int val) {               
			this.val = val;          
		}       
	}
	
	public static Node getFirstNodeInCycle(Node head) {         
		Node slow = head;          
		Node fast = head;             
		// 1) 找到快慢指针相遇点         
		while (fast != null && fast.next != null) {           
			slow = slow.next;              
			fast = fast.next.next;             
			if (slow == fast) { // Collision             
				break;            
			}           
		}              
		
		// 错误检查,这是没有环的情况         
		if (fast == null || fast.next == null) {            
			return null;         
		}  
		
		
		// 2)现在,相遇点离环的开始处的距离等于链表头到环开始处的距离,    
		// 这样,我们把慢指针放在链表头,快指针保持在相遇点,然后          
		// 同速度前进,再次相遇点就是环的开始处!          
		slow = head;            
		while (slow != fast) {          
			slow = slow.next;           
			fast = fast.next;        
		}            
		
		// 再次相遇点就是环的开始处      
		return fast;       
		
	}
	
}

本题建议画图理解!

你可能感兴趣的:(单链表——求两个单链表相交的第一个节点)