1. 程式人生 > >LeetCode演算法題160:相交連結串列解析

LeetCode演算法題160:相交連結串列解析

編寫一個程式,找到兩個單鏈表相交的起始節點。

例如,下面的兩個連結串列:

A:          a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3

在節點 c1 開始相交。

注意:
如果兩個連結串列沒有交點,返回 null.
在返回結果後,兩個連結串列仍須保持原有的結構。
可假定整個連結串列結構中沒有迴圈。
程式儘量滿足 O(n) 時間複雜度,且僅用 O(1) 記憶體。

這個題如果使用暴力迴圈的話複雜度就會很高,可能會達到O( n

2 n^2 ),所以這個方法不可取。換一種思路,連結串列其實只有後面的會相交,所以如果兩個連結串列長度相同的話,直接遍歷到兩個指標相同即可,如果長度不同,那就直接把長連結串列前面多的部分截掉,然後一起遍歷到兩個指標長度相同,這樣永遠只需要兩次迴圈即可。第一次遍歷獲得兩個連結串列的長度,第二次截掉前面多餘的然後尋找相交點。
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