1. 程式人生 > >牛客網線上程式設計專題《劍指offer-面試題37》兩個連結串列的第一個公共結點

牛客網線上程式設計專題《劍指offer-面試題37》兩個連結串列的第一個公共結點

題目連結:

題目描述:

解題思路:

首先遍歷兩個連結串列得到它們的長度,就能知道哪個連結串列比較長,以及長的連結串列比短的連結串列多幾個結點。在第二次遍歷的時候,在較長的連結串列上先走若干步,接著再同時在兩個連結串列上遍歷,找到的第一個相同的結點就是它們的第一個公共結點。

如上圖所示的兩個連結串列中,我們可以先遍歷一次得到它們的長度分別為5和4,也就是較長的連結串列與較短的連結串列相比多一個結點。第二次先在長的連結串列上走1步,到達結點2。接下來分別從結點2和結點4出發同時遍歷兩個結點,直到找到它們第一個相同的結點6,這就是我們想要的結果。

時間複雜度為O(m+n)。

已經AC的程式碼:

public class firstCommonNode {
	
	class ListNode{
		int val;
		ListNode next = null;
		
		public ListNode(int val) {
			// TODO Auto-generated constructor stub
			this.val = val;
		}
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		firstCommonNode ownClass = new firstCommonNode();
		ListNode l1_one = ownClass.new ListNode(1);
		ListNode l1_two = ownClass.new ListNode(2);
		l1_one.next = l1_two;
		ListNode l1_thr = ownClass.new ListNode(3);
		l1_two.next = l1_thr;
		ListNode l1_for = ownClass.new ListNode(6);
		l1_thr.next = l1_for;
		ListNode l1_fiv = ownClass.new ListNode(7);
		l1_for.next = l1_fiv;
		
		ListNode l2_one = ownClass.new ListNode(4);
		ListNode l2_two = ownClass.new ListNode(5);
		l2_one.next = l2_two;
		l2_two.next = l1_for;
		
		ListNode node = FindFirstCommonNode(l1_one, l2_two);
		System.out.println(node.val);
	}
	
	public static ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
		//得到兩個連結串列的長度
		int nLength1 = getListLength(pHead1);
		int nLength2 = getListLength(pHead2);
		//得到兩個連結串列長度之間的差值
		int nLengthDif = nLength1 - nLength2;
		
		ListNode pListHeadLong = null;
		ListNode pListHeadShort = null;
		if(nLengthDif >=0) {
			pListHeadLong = pHead1;
			pListHeadShort = pHead2;
		}else {
			pListHeadLong = pHead2;
			pListHeadShort = pHead1;
			nLengthDif = nLength2 - nLength1;
		}
		
		// 先在長連結串列上走幾步,再同時在兩個連結串列上遍歷
		for(int i=0; i<nLengthDif; i++) {
			pListHeadLong = pListHeadLong.next;
		}
		
		// 同時在兩個連結串列上遍歷
		while((pListHeadLong != null) && (pListHeadShort != null) && (pListHeadLong != pListHeadShort)) {
			pListHeadLong = pListHeadLong.next;
			pListHeadShort = pListHeadShort.next;
		}
		
		//得到第一個公共結點
		ListNode pFirstCommonNode = pListHeadLong;
		return pFirstCommonNode;
	}
	
	public static int getListLength(ListNode pHead) {
		int nLength = 0;
		ListNode pNode = pHead;
		while(pNode != null) {
			nLength++;
			pNode = pNode.next;
		}
		return nLength;
	}

}