兩個相交鍊錶

2021-09-24 02:13:35 字數 3510 閱讀 7633

兩個單鏈表相交的一系列問題

【題目】 在本題中,單鏈表可能有環,也可能無環。給定兩個單鏈表的頭節點 head1和head2,這兩個鍊錶可能相交,也可能

不相交。請實現乙個函式, 如果兩個鍊錶相交,請返回相交的第乙個節點;如果不相交,返回null 即可。 要求:如果鍊錶1

的長度為n,鍊錶2的長度為m,時間複雜度請達到 o(n+m),額外空間複雜度請達到o(1)。

單鏈表的相交的情況:

判斷兩個鍊錶是有環還是無環
方式一:判斷鍊錶是否有環可以通過乙個map來實現:遍歷鍊錶,判斷該節點是否在map,如果存在,則表明該節點是入環的節點;如果不存在,就把該節點放入map集合中,遍歷完都沒有碰見相同的節點,則表明該煉表無環。

方式二:設定兩個指標,乙個快指標一次走兩步、乙個慢指標一次走一步。遍歷鍊錶,如果兩個指標相遇了,即表明該鍊錶是有環的,而且相遇的節點在環上,並且該節點到入環點的距離與頭節點到入環點的距離是相等的,那麼可以讓快指標重新指向頭節點,速度與慢指標一樣一次一步,當兩個指標再次相遇時,則表明相遇的節點即為入環點;如果快指標走到頭了(null),則表明該鍊錶是無環鏈表。

根據有環無環的情況分出三類情況分別進行判斷
判斷兩個無環單鏈表是否相交

分別遍歷兩個無環單鏈表,得出各自的長度和尾節點。

如果尾節點相等,則表明相交,此時拿長鍊錶的長度減去短鍊表的長度,長鍊表先走這個差值的步數,然後兩個鍊錶一起走,他們相遇時的節點即為相交節點

如果兩個鍊錶的尾節點不相等,則表明這兩個單鏈表不相交。

判斷兩個有環單鏈表是否相交

先比較兩個有環單鏈表的入環節點,如果入環節點相等,則表明兩個鍊錶是相交的,為圖中的第二種情況,此時除去環,就是兩個無環單鏈表的相交的情況,同上的步驟

如果入環節點不相等,則可能是相交也可能是不相交的,此時遍歷其中乙個單鏈表,如果在遍歷的過程中碰到了另外乙個單鏈表的入環節點,則表明這兩個有環單鏈表是相交的(圖中第三中情況,無論哪個入環節點都可以算作第乙個相交點);遍歷完後,都沒有碰見另外乙個鍊錶的入環節點,則表明是不相交的。

乙個無環單鏈表和乙個有環單鏈表無法相交

package struct;

public

class

findfirstintersectnode

}//主體方法

public

static node getintersectnode

(node head1,node head2)

//獲取到兩個鍊錶的入環節點

node loop1 =

getloopnode

(head1)

; node loop2 =

getloopnode

(head2);if

(loop1 == null && loop2 == null)

else

if(loop1 != null && loop2 != null)

else

}//獲取乙個單鏈表的入環節點;沒有環,則返回null

public

static node getloopnode

(node head)

//設定兩個指標

node small = head.next;

node fast = head.next.next;

//如果有環,快指標與慢指標終會在環上相遇

while

(small != fast)

small = small.next;

fast = fast.next.next;

}//相遇後,快指標指向頭節點,且與慢指標保持一樣的速度,那麼它們會在如環節點相遇

fast = head;

while

(small != fast)

//返回入環節點

return small;

}//兩個鍊錶都是沒有環

public

static node noloop

(node head1, node head2)

node cur1 = head1;

node cur2 = head2;

int len =0;

//得到鍊錶的長度,並且得到尾節點

while

(cur1.next != null)

//得到該鍊錶與上乙個鍊錶的長度的差值,並且得到尾節點

while

(cur2.next != null)

//兩個單鏈表的尾節點不相等,則表明沒有相交

if(cur1 != cur2)

//兩個單鏈表相交

cur1 = len >

0? head1 : head2;

//cur1指向長鍊表的頭結點

cur2 = cur1 == head1 ? head2 : head1;

//cur2指向另外乙個鍊錶的頭結點

len = math.

abs(len)

;//長度差值取絕對值

//先讓長鍊錶走差值步

while

(len !=0)

while

(cur1 != cur2)

//得到入環節點

return cur1;

}//兩個鍊錶都是有環鏈表

public

static node bothloop

(node head1,node loop1,node head2,node loop2)

while

(cur2 != loop2)

cur1 = len >

0? head1 : head2;

cur2 = cur1 == head1 ? head2 : head1;

len = math.

abs(len)

;while

(len !=0)

while

(cur1 != cur2)

return cur1;

}else

cur1 = cur1.next;

}return null;}}

public

static

void

main

(string[

] args)

}

下面依次為三個例子的例項

鍊錶 兩個鍊錶的相交問題

1.分析 在已知鍊錶不帶環時,如果兩個鍊錶的尾部相同則相交,用快慢指標求交點。listnode getmeetnode listnode list1,listnode list2 判斷相交點 while cur2 listnode longlist list1 listnode shortlist ...

判斷兩個鍊錶是否相交

思路1 最暴力的辦法,針對鍊錶1的每乙個節點,判斷其是否也在鍊錶2中,複雜度o n m 明顯不是乙個好方法。思路2 給每個節點增加乙個標記量,可以是附在鍊錶中的成員,也可以是另外的乙個結構,例如用乙個陣列來儲存。先遍歷鍊錶1,標記出遍歷過的節點,再遍歷鍊錶2,如果發現某個節點已經被遍歷過,則說明相交...

判斷兩個鍊錶是否相交

參考 判斷兩個鍊錶是否相交 假設兩個鍊錶都沒有環 有以下三種方法 1 判斷第乙個鍊錶的每個節點是否在第二個鍊錶中 2 把第二個鍊錶連線到第乙個後面,判斷得到的鍊錶是否有環,有環則相交 3 先遍歷第乙個鍊錶,記住最後乙個節點,再遍歷第二個鍊錶,得到最後乙個節點時和第乙個鍊錶的最後乙個節點做比較,如果相...