1.題目描述
編寫一個程序,找到兩個單鏈表相交的起始節(jié)點(diǎn)。
如下面的兩個鏈表:
在節(jié)點(diǎn) c1 開始相交。
示例 1:
輸入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
輸出:Reference of the node with value = 8
輸入解釋:相交節(jié)點(diǎn)的值為 8 (注意,如果兩個列表相交則不能為 0)。從各自的表頭開始算起,鏈表 A 為 [4,1,8,4,5],鏈表 B 為 [5,0,1,8,4,5]。在 A 中,相交節(jié)點(diǎn)前有 2 個節(jié)點(diǎn);在 B 中,相交節(jié)點(diǎn)前有 3 個節(jié)點(diǎn)。
示例2:
輸入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
輸出:Reference of the node with value = 2
輸入解釋:相交節(jié)點(diǎn)的值為 2 (注意,如果兩個列表相交則不能為 0)。從各自的表頭開始算起,鏈表 A 為 [0,9,1,2,4],鏈表 B 為 [3,2,4]。在 A 中,相交節(jié)點(diǎn)前有 3 個節(jié)點(diǎn);在 B 中,相交節(jié)點(diǎn)前有 1 個節(jié)點(diǎn)。
示例 3:
輸入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
輸出:null
輸入解釋:從各自的表頭開始算起,鏈表 A 為 [2,6,4],鏈表 B 為 [1,5]。由于這兩個鏈表不相交,所以 intersectVal 必須為 0,而 skipA 和 skipB 可以是任意值。
解釋:這兩個鏈表不相交,因此返回 null。
注意:
- 如果兩個鏈表沒有交點(diǎn),返回
null
. - 在返回結(jié)果后,兩個鏈表仍須保持原有的結(jié)構(gòu)。
- 可假定整個鏈表結(jié)構(gòu)中沒有循環(huán)。
- 程序盡量滿足
O(n)
時間復(fù)雜度,且僅用O(1)
內(nèi)存。
2.分析
- 錯誤示范:首先我想到的是
O(n^2)
的算法方式,也就是遍歷鏈表A的同時遍歷鏈表B,看他們是否有相同節(jié)點(diǎn),當(dāng)然結(jié)局就是時間超限。 - 偷瞄下前輩們寫法,獲得經(jīng)驗是先獲取這兩個鏈表的長度,再搞個差幾步,然后長的那個鏈表提起走這幾步,就可以一次遍歷中同時遍歷鏈表A和鏈表B,實(shí)現(xiàn)時間復(fù)雜度為
O(n)
。 - ① 取到鏈表A和鏈表B的長度
- ②將鏈表B定義為較長的鏈表
- ③ 移動鏈表B的頭結(jié)點(diǎn)(使得它和鏈表A的頭結(jié)點(diǎn)并駕齊驅(qū))
- ④循環(huán)著兩個鏈表,當(dāng)找到相同的節(jié)點(diǎn)時,返回那個節(jié)點(diǎn)(此時ori_headA == ori_headB),要是找不到最后ori_headA也會變成None
3.解決
class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
# ① 取到鏈表A和鏈表B的長度
len_A = 0
len_B = 0
ori_headA = headA
ori_headB = headB
while headA:
len_A += 1
headA = headA.next
while headB:
len_B += 1
headB = headB.next
# ②將鏈表B定義為較長的鏈表
if len_A > len_B:
# 這一步保障ori_headB為較長的鏈
len_A, len_B, ori_headA, ori_headB = len_B, len_A, ori_headB, ori_headA
exa_num = len_B - len_A
# ③ 移動鏈表B的頭結(jié)點(diǎn)(使得它和鏈表A的頭結(jié)點(diǎn)并駕齊驅(qū))
while exa_num and ori_headB:
exa_num -= 1
ori_headB = ori_headB.next
# ④循環(huán)著兩個鏈表,當(dāng)找到相同的節(jié)點(diǎn)時,返回那個節(jié)點(diǎn)(此時ori_headA == ori_headB),要是找不到最后ori_headA也會變成None
while ori_headA:
if ori_headA == ori_headB:
return ori_headA
ori_headA = ori_headA.next
ori_headB = ori_headB.next
return ori_headA