1. 程式人生 > >騰訊//相交連結串列

騰訊//相交連結串列

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

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

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

在節點 c1 開始相交。

注意:

如果兩個連結串列沒有交點,返回 null.

在返回結果後,兩個連結串列仍須保持原有的結構。

可假定整個連結串列結構中沒有迴圈。

程式儘量滿足 O(n) 時間複雜度,且僅用 O(1) 記憶體。

方法:

  • 將其中一個連結串列的頭尾相連,問題轉化為求環入口節點
  • 用兩個棧分別記錄兩個連結串列的節點,再彈出,找到最後一個相等的節點
  • 將長的連結串列移動長度差的距離,然後同時移動兩個連結串列,找到第一個相等的節點
/**
 * 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) {
        auto lenA = listLength(headA);
        auto lenB = listLength(headB);
        if(lenA > lenB){
            for(auto i = 0; i != lenA - lenB; i++){
                headA = headA->next;
            }
        }else{
            for(auto i = 0; i < lenB - lenA; i++){
                headB = headB->next;
            }
        }
        while(headA&&headB&&headA!=headB){
            headA = headA->next;
            headB = headB->next;
        }
        return headA;
    }
    private:
        int listLength(ListNode *head){
            int len = 0;
            while(head){
                len++;
                head = head->next;
            }
            return len;
        } 
};