leetcode 160相交链表

人盡茶涼 提交于 2020-02-09 04:12:30

暴力解法当然可以遍历两个链表,不过time O(mn) space O(1)暂且不说,

方法一:双指针,

time O(m+n),space O(1)

可以对比判断环形链表的快慢指针法。

这种方法构思十分十分十分巧妙,假设有两个链表,链表A:  1 2 3 * #    和链表B:   a b c d e * #  ,可以得出相交的第一个节点为*。那么A长度为la=5,*前面有lapre=3个元素;B长度为lb=7,*前面有lbpre=5个元素;可以发现lbpre+la=lapre+lb。

因此,只要用两个指针,每次前进一个节点,当pA到达末尾让其指向headB,当pB到达末尾让其指向headA那么当遍历10次后,两个指针都刚好到达*处,因此得到结果。

同时,针对无解的情况,记录两个链表的长度m和n,并且记录遍历次数i如果i>m+n时还没有满足条件的节点,可以断定无解;或者记录到达NULL的次数,如果第三次到达NULL之前还没有解,那么则无解。

/**
 * 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,*pB=headB;
        if(pA==NULL || pB==NULL) return NULL;
        int cnt=0;//记录到达链表终点的次数
        while(cnt<=2){
            if(pA==pB) return pA;
            pA=pA->next;
            pB=pB->next;
            if(pA==NULL) {cnt++;pA=headB;}
            if(pB==NULL) {cnt++;pB=headA;}
        }
        return NULL;
    }
};

进阶版:因为无解的话最终pA和pB在(m+n)次执行后都会同时指向NULL,因此当pA==pB时断开循环return即可。这样可以缩短代码长度

/**
 * 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,*pB=headB;
        while(pA!=pB){
            pA=pA?pA->next:headB;
            pB=pB?pB->next:headA;
        }
        return pA;
    }
};

方法二:

使用哈希表O(n)时间,O(n)空间

/**
 * 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) {
        unordered_map<ListNode*,int> m;
        ListNode *pa=headA,*pb=headB;
        while(pa!=NULL){
            m[pa]=1;pa=pa->next;
        }
        while(pb!=NULL){
            if(m[pb]==1) return pb;
            pb=pb->next;
        }
        return NULL;
    }
};

 方法三:

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!