zoukankan      html  css  js  c++  java
  • leetcode 160相交链表

    暴力解法当然可以遍历两个链表,不过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;
        }
    };

     方法三:

  • 相关阅读:
    Jasper 常用知识点总结
    Linux
    搭建spring项目,无法创建RequestMappingHandlerMapping异常
    pom.xml文件设置
    MySQL的常用JSON函数
    SQL中的条件判断语句(case when zhen if,ifnull)用法
    sql查询原理
    sql积累
    Linux常用命令大全
    mysql中group by 的用法解析
  • 原文地址:https://www.cnblogs.com/joelwang/p/10918997.html
Copyright © 2011-2022 走看看