LeetCode演算法題160:相交連結串列解析
阿新 • • 發佈:2018-11-11
編寫一個程式,找到兩個單鏈表相交的起始節點。
例如,下面的兩個連結串列:
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
在節點 c1 開始相交。
注意:
如果兩個連結串列沒有交點,返回 null.
在返回結果後,兩個連結串列仍須保持原有的結構。
可假定整個連結串列結構中沒有迴圈。
程式儘量滿足 O(n) 時間複雜度,且僅用 O(1) 記憶體。
這個題如果使用暴力迴圈的話複雜度就會很高,可能會達到O(
),所以這個方法不可取。換一種思路,連結串列其實只有後面的會相交,所以如果兩個連結串列長度相同的話,直接遍歷到兩個指標相同即可,如果長度不同,那就直接把長連結串列前面多的部分截掉,然後一起遍歷到兩個指標長度相同,這樣永遠只需要兩次迴圈即可。第一次遍歷獲得兩個連結串列的長度,第二次截掉前面多餘的然後尋找相交點。
C++原始碼:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *pA = headA;
ListNode *pB = headB;
int lenA = 0, lenB = 0;
while(pA!=NULL || pB!=NULL){
if (pA!=NULL){
lenA++;
pA = pA-> next;
}
if (pB!=NULL){
lenB++;
pB = pB->next;
}
}
pA = headA;
pB = headB;
if (lenA>lenB){
int diff = lenA - lenB;
while(diff--)
pA = pA->next;
}
if(lenB>lenA){
int diff = lenB - lenA;
while(diff--)
pB = pB->next;
}
while(pA!=pB){
pA = pA->next;
pB = pB->next;
}
return pA;
}
};
python3原始碼:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
pA = headA
pB = headB
lenA = 0
lenB = 0
while pA!=None or pB!=None:
if pA!=None:
lenA += 1
pA = pA.next
if pB!=None:
lenB += 1
pB = pB.next
pA = headA
pB = headB
if lenA > lenB:
diff = lenA - lenB
while diff:
pA = pA.next
diff -= 1
if lenB > lenA:
diff = lenB - lenA
while diff:
pB = pB.next
diff -= 1
while pA!=pB:
pA = pA.next
pB = pB.next
return pA