leetcode160——Intersection Of Two Linked Lists

題目大意:在時間複雜度O(m+n),空間複雜度O(1)的條件下找到兩個鏈表的相交結點

分析:暴力的時間複雜度爲O(mn),肯定不可取。最初的思路是用哈希表記錄已遍歷的結點。但是空間複雜度爲O(m)或O(n)。

方法:雙指針。p和q分別從headA和headB開始遍歷,當p到尾結點(空)時,p返回指向headB;當q到尾結點(空)時,q返回指向headA。當循環遍歷中p和q相遇時即爲相交結點。因爲兩鏈表如果有相交,就意味着尾結點一定相同,假設重疊部分結點c個,不重疊部分分別a、b個,則p和q走過的路程可表示爲:a->c->b=b->c->a。所以可以採用雙指針到達尾結點重返另一鏈表頭結點的方式,來找到相交結點。

代碼:

雙指針

/**
 * 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) {
        if(headA == NULL || headB == NULL) return NULL;
        ListNode* p = headA;
        ListNode* q = headB;
        while(p != q){
            p = p->next;
            q = q->next;
            if(p == NULL && q == NULL) return NULL;
            if(p == NULL) p = headB;
            if(q == NULL) q = headA;
        }
        return p;
    }
};

哈希表

/**
 * 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) {
        if(headA == NULL || headB == NULL) return NULL;
        unordered_set<ListNode*> s;
        ListNode* p = headA;
        ListNode* q = headB;
        while(p || q){
            if(p){
                if(s.find(p) != s.end()) return p;
                s.insert(p);
                p = p->next;
            }
            if(q){
                if(s.find(q) != s.end()) return q;
                s.insert(q);
                q = q->next;
            }
        }
        return NULL;
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章