力扣160. 相交链表(2012年408真题)

113 阅读1分钟

解法一

利用哈希存取每一个节点的地址

时间复杂度 O(max(n,m))O(max(n, m)),空间复杂度O(max(n,m))O(max(n, m))

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        map<ListNode *, bool> mp;
        for(ListNode *i = headA; ; i = i -> next) {
            if(i == NULL) break;
            mp[i] = 1;
        }
        ListNode *ans = NULL;
        for(ListNode *i = headB; ; i = i -> next) {
            if(i == NULL) break;
            if(mp[i]) {
                ans = i;
                break;
            }
        }
        return ans;
    }
};

解法二

假设两个链表的长度之差为 delta|delta|,那么只需要让长的链表将前 delta|delta| 的节点但删掉; 可以利用反证法证明,最长相交链表的最长长度一定是较短链表的长度

时间复杂度 O(max(n,m))O(max(n, m)), 空间复杂度O(1)O(1)

class Solution {
public:
    int getLength(ListNode *l) {
        int len = 0;
        for(ListNode *i = l;; i = i-> next) {
            if(i == NULL) break;
            len ++;
        }
        return len;
    }

    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode *longList = headA, *shortList = headB, *ans = NULL;
        int delta = getLength(headA) - getLength(headB);
        if(delta < 0) {
            longList = headB;
            shortList = headA;
        }
        delta = abs(delta);
        for(int i = 1; i <= delta; i ++) {
            longList = longList -> next;
        }
        ListNode *j = shortList;
        for(ListNode *i = longList;; i = i -> next, j = j -> next) {
            if(j == NULL) break;
            if(i == j) {
                ans = j;
                break;
            }
        }
        return ans;
    }
};

解法三

利用与刚刚相同的思路,有两个指针分别按照链表 A>BA->BB>AB->A 遍历,那么其中一定会找到相交链表

时间复杂度 O(max(n,m))O(max(n, m)), 空间复杂度O(1)O(1)

class Solution {
public:
    int getLength(ListNode *l) {
        int len = 0;
        for(ListNode *i = l;; i = i-> next) {
            if(i == NULL) break;
            len ++;
        }
        return len;
    }

    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode *pa = headA, *pb = headB, *ans = NULL;
        while(true) {
            if(pa == NULL and pb == NULL) break;
            if(pa == pb) {
                ans = pa;
                break;
            }
            if(pa == NULL) pa = headB;
            else pa = pa -> next;
            if(pb == NULL) pb = headA;
            else pb = pb -> next;
        }
        return ans;
    }
};