LeetCode题解--160. 相交链表

题目

编写一个程序,找到两个单链表相交的起始节点。
例如,下面的两个链表:
A: a1 → a2

c1 → c2 → c3

B: b1 → b2 → b3
在节点 c1 开始相交。
注意:
如果两个链表没有交点,返回 null.
在返回结果后,两个链表仍须保持原有的结构。
可假定整个链表结构中没有循环。
程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。

分析

  题目重点在于要求满足时间复杂度是O(n)以及空间复杂度O(1)。
  空间角度:由于需要遍历链表,那么一定需要游标指针,因此,不能够开辟更多的空间;
  时间角度:难点在于如何保证时间是O(n)。因为两个链表的长度不一致,因此,在出现交点之前的节点数量不一致,因此,不能够通过逐个比较的方式。如果采取暴力的方式比较,那么一定是两层循环,则时间不满足要求。
  关键问题在于出现交点之前两个链表的节点数不一致
  存在一个trick就是,假设两个链表的游标记为pA和pB,那么只要pA和pB都经历一遍链表1前面的节点以及链表2前面的节点,那么两个游标就会在交点处相遇。就好比整数求和中(2+3)+3 = (3+2)+3,两个游标走过的路径长度都是8。
  以上面的例子为例,当pA走到c3的时候,pB走到C2,此时,只要让pA指向b1,当pB到尾部的时候,指向a1,那么pA和pB就会在c1处相遇。
  另外,需要考虑,如果没有交点,那么按照上面的方式,两个游标将不断进行下去,因此,解决的方法是设定一个计数器count。如果两个链表存在交点,那么pA触碰一次表1尾,pB触碰一次表2尾一定会找到交点,如果某一个游标触发了第三次尾部,那么一定不存在交点。

算法

  1. 特殊情况1,两个表的头节点中有一个是空,那么没有交点;
  2. 特殊情况2,如果头指针相等,那么交点就是头指针;
  3. 当pA不等于pB的时候循环,设置计数器count=0;
  4. 如果pA->NULL,pA指向表2的head,count++,否则pA=pA->next;
  5. 如果pB->NULL,pB指向表1的head,count++,否则pB=pB->next;
  6. 最后退出循环,如果pA==pB,则是交点,返回,否则没有找到交点,返回NULL。

C++程序

ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        //有一个列表为空,则交点为空
        if(headA==NULL||headB==NULL){
            return NULL;
        }
        //头节点就相等
        if(headA==headB) return headA;
        ListNode* pA = headA, *pB = headB;
        int count = 0;
        while(pA!=pB&&count<3){                        
            if(pA->next==NULL) {
                pA = headB;
                count++;
            }
            else pA = pA->next;
            if(pB->next==NULL){                
                pB = headA;
                count++;
            }
            else pB = pB->next;            
        }
        if(pA==pB) return pA;
        else return NULL;
    }

猜你喜欢

转载自blog.csdn.net/qq_33297776/article/details/81023344