兩個單鏈表相交的一系列問題
【題目】 在本題中,單鏈表可能有環,也可能無環。給定兩個單鏈表的頭節點 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 先遍歷第乙個鍊錶,記住最後乙個節點,再遍歷第二個鍊錶,得到最後乙個節點時和第乙個鍊錶的最後乙個節點做比較,如果相...