1. 程式人生 > >判斷兩個單鏈表是否相交--java實現

判斷兩個單鏈表是否相交--java實現

題目描述:單鏈表可能有環,也可能無環。給定兩個單鏈表的頭節點 head1 和 head2, 這兩個連結串列可能相交,也可能不相交。請實現一個函式,如果兩個連結串列相交,請返回相交 的第一個節點;如果不相交,返回 null 即可。

首先,感謝程雲老師的分享!以下是本問題的解決方法整理。

思路:

       連結串列分有環連結串列和無環連結串列,如果兩個連結串列存在相交,則只有兩種可能,兩個連結串列都無環或者都有環。

(1)如果連結串列都無環,則先判斷連結串列的尾指標是否一樣,如果不一樣,則沒有相交。如果一樣,則找出兩個連結串列的長度差,將兩個連結串列從距離尾節點同樣的距離進行掃描,如果相交,則必然有一處掃描節點相同。例項資料List1:1->2->3->4->5->6->7->null,List2:0->9->8->6->7->null,第一個相交節點為6

示例圖如下,


                                                                                                                   

(2)如果連結串列都有環,則只肯能有下面兩種情況(如下圖)。兩種情況區分的方法為:入環點是否相同。

         如果相同則為第一種情況:那麼查詢第一個相交點與無環的單鏈表相交找第一個交點的方法一樣。

         如果入環點不同,則為第二種情況,這個相交點或者為list1 的入環點loop1或者為list2的入環點loop2。

情況1例項資料(List1:1->2->3->4->5->6->7->4,List2:0->9->8->2->3->4->5->6->7->4,第一個交點為2

情況2例項資料(List1:1->2->3->4->5->6->7->4,List2:0->9->8->6->7->4->5->6,第一個交點為4或6

                                              

下面為實現程式碼

public static class Node {
		public int value;
		public Node next;

		public Node(int data) {
			this.value = data;
		}
	}
/*判斷是否相交,如果相交,得到第一個相交點*/
	public static Node getIntersectNode(Node head1, Node head2) {
		if (head1 == null || head2 == null) {
			return null;
		}
		Node loop1 = getLoopNode(head1);
		Node loop2 = getLoopNode(head2);
		if (loop1 == null && loop2 == null) {
			return noLoop(head1, head2);
		}
		if (loop1 != null && loop2 != null) {
			return bothLoop(head1, loop1, head2, loop2);
		}
		return null;
	}
/*
 * 判斷是否存在環,如果存在,則找出環的入口點。
 * 入口點找法:快慢指標,塊指標走兩步,滿指標走一步,如果存在迴圈,則在慢指標走完環前,總會和快指標相遇。
 * 從頭指標和相遇點同時向後走,相遇的點必定是入口點。*/
	public static Node getLoopNode(Node head) {
		if (head == null || head.next == null || head.next.next == null) {
			return null;
		}
		Node n1 = head.next; // n1 -> slow
		Node n2 = head.next.next; // n2 -> fast
		while (n1 != n2) {
			if (n2.next == null || n2.next.next == null) {
				return null;
			}
			n2 = n2.next.next;
			n1 = n1.next;
		}
		n2 = head; // n2 -> walk again from head
		while (n1 != n2) {
			n1 = n1.next;
			n2 = n2.next;
		}
		return n1;
	}
/*無環時的判斷方法*/
	public static Node noLoop(Node head1, Node head2) {
		if (head1 == null || head2 == null) {
			return null;
		}
		Node cur1 = head1;
		Node cur2 = head2;
		int n = 0;
		while (cur1.next != null) {
			n++;
			cur1 = cur1.next;
		}
		while (cur2.next != null) {
			n--;
			cur2 = cur2.next;
		}
		if (cur1 != cur2) {
			return null;
		}
		cur1 = n > 0 ? head1 : head2;
		cur2 = cur1 == head1 ? head2 : head1;
		n = Math.abs(n);
		while (n != 0) {
			n--;
			cur1 = cur1.next;
		}
		while (cur1 != cur2) {
			cur1 = cur1.next;
			cur2 = cur2.next;
		}
		return cur1;
	}
/*有環時的判斷方法*/
public static Node bothLoop(Node head1, Node loop1, Node head2, Node loop2) {
		Node cur1 = null;
		Node cur2 = null;
		if (loop1 == loop2) {
			cur1 = head1;
			cur2 = head2;
			int n = 0;
			while (cur1 != loop1) {
				n++;
				cur1 = cur1.next;
			}
			while (cur2 != loop2) {
				n--;
				cur2 = cur2.next;
			}
			cur1 = n > 0 ? head1 : head2;
			cur2 = cur1 == head1 ? head2 : head1;
			n = Math.abs(n);
			while (n != 0) {
				n--;
				cur1 = cur1.next;
			}
			while (cur1 != cur2) {
				cur1 = cur1.next;
				cur2 = cur2.next;
			}
			return cur1;
		} else {
			cur1 = loop1.next;
			while (cur1 != loop1) {
				if (cur1 == loop2) {
					return loop1;
				}
				cur1 = cur1.next;
			}
			return null;
		}
	}
另:判斷是否單鏈表是否有環可以使用雜湊表進行判斷。
最後,關於如何找環的入口點問題,可以參考文章:http://blog.csdn.net/wongson/article/details/8019228,

相關推薦

判斷單鏈是否相交--java實現

題目描述:單鏈表可能有環,也可能無環。給定兩個單鏈表的頭節點 head1 和 head2, 這兩個連結串列可能相交,也可能不相交。請實現一個函式,如果兩個連結串列相交,請返回相交 的第一個節點;如果不相交,返回 null 即可。 首先,感謝程雲老師的分享!以下是本問題

java判斷單鏈是否相交

fast n) detail 無環 etl ++ code 數據 enter 轉載於:http://blog.csdn.net/happymatilian/article/details/47811161 思路: 鏈表分有環鏈表和無環鏈表,如果兩個鏈表存在相交

java 判斷單鏈是否相交

文章目錄題目思考原始碼環的入口 題目 單鏈表可能有環,也可能無環。給定兩個單鏈表的頭節點 head1 和 head2, 這兩個連結串列可能相交,也可能不相交。請實現一個函式,如果兩個連結串列相交,請返回相交的第一個節點;如果不相交,返回 null 即可。 思考

判斷單鏈是否相交,若相交,求節點(連結串列不帶環)

先理解一下題目的意思,單鏈表的相交和普通兩條線的相交一樣嗎? 所以當我們把其換成節點就可以變成下面這樣: 先判斷連結串列是否相交,我們可以運用兩個連結串列相交後就變成了一條連結串列這個特性來判斷,因為如果兩條連結串列相交,那麼這兩條連結串列的最後一個節點一定

判斷單鏈是否存在環,判斷連結串列是否相交問題詳解

有一個單鏈表,其中可能有一個環,也就是某個節點的next指向的是連結串列中在它之前的節點,這樣在連結串列的尾部形成一環。問題:1、如何判斷一個連結串列是不是這類連結串列?2、如果連結串列為存在環,如何找到環的入口點?解答:一、判斷連結串列是否存在環,辦法為:設定兩個指標(fast, slow),初始值都指向頭

算法總結之 單鏈相交的一些列問題

找到 開始 兩種 end 相交 說明 移動 一個 返回 單鏈表,可能有環,也可能無環。給定兩個單鏈表的頭節點head1 和 head2 這兩個鏈表可能交也可能不交。實現函數,如果相交,請返回相交的第一個節點,不交返回null 這道題目需要分析的情況非常 本題拆分

演算法題008 -- [寫一個程式找出單鏈的交叉節點] by java

題目 寫一個程式找出兩個單鏈表的交叉節點。 演算法要求: 如果兩個連結串列沒有交叉點,就返回null 這兩個連結串列必須在方法結束後保持他們原來的資料結構 你可以認定在連結串列的結構不存在環 時間複雜度O(n), 空間複雜度O(1) 舉例

單鏈相交的系列問題

題目 在本題中,單鏈表可能有環,也可能無環。給定兩個單鏈表的頭節點 head1和head2,這兩個連結串列可能相交,也可能不相交。請實現一個函式, 如果兩個連結串列相交,請返回相交的第一個節點;如果不相交,返回null 即可。 要求:如果連結串列1的長度為N,連結串列2的長度為M,時間複

java實現---判斷連結串列是否相交,若相交,求交點(假設連結串列不帶環)

有兩個單鏈表,判斷它們是否相交,若相交,求交點 第一步判斷兩個連結串列是否相交 第二步求交點 第一步判斷兩個連結串列是否相交 如果兩個連結串列相交,那麼它們的

資料結構: 單鏈相交的一系列問題

資料結構: 兩個單鏈表相交的一系列問題 這個是一個比較綜合的問題: 若兩個單鏈表一個為有環,一個無環. 那麼肯定不能相交. 若二者都沒有環, 問題就轉化為 兩個無環單鏈表是否相交,方法就是 快慢指標 ,是否能找到第一個相交的節點. 若二者都有環,那麼問題

Java程式碼 判斷連結串列是否相交

題目:判斷兩個單向連結串列是否相交,假設兩個連結串列均不存在環 演算法思路:有兩種方法,第一種方法就是在其中一個連結串列上順序遍歷每個節點,每遍歷一個節點的時候,在另外一個連結串列上順序遍歷每個節點,如果便利過程中發現兩個節點相同,說明此時連結串列相交,也就找到了他們的第一

單鏈交點and判斷連結串列是否有環

求單鏈表交點演算法: 先求得兩條連結串列各自的長度,如果最後一個節點的地址相同,則確定連結串列有交點。然後求出長度差值k,讓長的連結串列指標先走k步,然後兩個連結串列指標同時走,邊走邊比較,第一次相等處即是交點。 程式碼: struct Node { int

合併單鏈(連結串列方式)

假設頭指標為La、Lb單鏈表分別為線性表LA、LB的儲存結構,現在要合併La、Lb得到單鏈表Lc void MergeList_L(LinkList La, LinkList Lb, LinkList Lc){ //已知La、Lb的元素按值非遞減排列 //歸併La、Lb得到單鏈表Lc,

單鏈合併成一個單鏈,L1,L2 —>L3

將兩個單鏈表合併成一個單鏈表 假設L1=(x1,x2,x3……Xn)長度為n L2=(y1,y2,y3………Ym)長度為m 若m<n,則L3=(x1,y1,x2,y2,x3,y3………………Xn,Yn,Yn+1,Yn+2……Ym); 若m>n,則L3=(x1,y1,x

判斷連結串列是否相交,若相交,求交點。(假設連結串列不帶環)

判斷是否相交 int IsCrossWithoutCircle(pList plist1, pList plist2) { pNode pTail1 = plist1; pNode pTail2 = plist2; if (pTail1 == NULL || pTai

【資料結構】連結串列相關練習題:判斷連結串列是否相交

編寫一個程式,找到兩個單鏈表相交的起始節點。 例如,下面的兩個連結串列: A: a1 → a2 ↘ c1 → c2 → c3 ↗

資料結構——找單鏈的交叉點,並將交叉點在連結串列ls1中所處的位置打印出來

1、程式檔案 I、 在交叉點/src目錄下分別建立main.c、Linklist.c檔案 //main.c #include <stdio.h> #include <stdlib.h> //包括rand()、srand()、abs()等函式 #include &

【連結串列問題】判斷無環單鏈是否相交

目錄   題目 思路 雜湊表判斷兩連結串列是否相交 根據連結串列相交性質判斷 題目 現在有兩個無環單鏈表,若兩個連結串列的長度分別為m和n,判斷這兩個連結串列是否相交。 給定兩個連結串列的頭結點headA和headB,請返回一個bool值,代表這兩個連結