再从萌新开始-Leetcode每日题解-160. Intersection of Two Linked Lists

160Intersection of Two Linked Lists(easy)

Write a program to find the node at which the intersection of two singly linked lists begins.

For example, the following two linked lists:

A:          a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3

begin to intersect at node c1.

Notes:

  • If the two linked lists have no intersection at all, return null.
  • The linked lists must retain their original structure after the function returns.
  • You may assume there are no cycles anywhere in the entire linked structure.
  • Your code should preferably run in O(n) time and use only O(1) memory.

Credits:
Special thanks to @stellari for adding this problem and creating all test cases.

-----------------------------------------------------------------分割线--------------------------------------------------------------------------------------------------------------------

开始写题解的第二天,周日一大早就起来忙活,真是佩服自己的热情…希望能多坚持一会儿…

又拿了一道水题(误),仔细读了以后发现似乎并不水啊…题目要求找到两个无环链表的公共段的起始点(示意图已经很清楚了),如果没有公共段,则返回NULL。要求不能更改输入链表的结构,时间要求为O(n),空间要求O(1)。


分析一下,因为有可能并没有公共段,那至少两个链表都需要遍历一遍,时间O(n)也只能刚刚好是满足,空间O(1)加上不能更改链表,直接就堵死了统计的这条路,而且题目并没有说链表的val是唯一的,要判断公共点还是要靠地址…

唯一想到的就是之前判断链表是否有环的方法,利用一快一慢两个指针,可是这样时间复杂度有可能会退化到O(n^2),也没办法解决无公共端点的情况。面对一道easy尝试一个多小时都没有进展,心态炸了,手贱去看了discuss,以下就讲解以下其他人的方法吧:


根据题目已经,可以把链表分成3部分,A链独有部分(用A表示),B链独有部分(用B表示),公共的部分(用C表示)。解题的核心就是抓住一点:

A + C + B = B + C + A 


同时用两个指针p1,p2,分别从链表A的头部和链表B的头部开始遍历。当p1遍历完链表A,到达尾部以后,接着从链表B头部开始遍历;p2同理,遍历完链表B以后从链表A头部开始遍历。可以证明在O(n)时间(只需要遍历一遍A+B)一定能够找到公共起始点。如果两个指针同时到达链表的尾部NULL,那么说明C为空集,没有公共部分。


代码:

class Solution{                                                      
public:     
    ListNode *getIntersectionNode(ListNode *headA,ListNode *headB){
        ListNode* tmpA = headA;
        ListNode* tmpB = headB;
            
        while(1){
            if (tmpA == NULL && tmpB == NULL) return NULL;
            else if (tmpA == tmpB) return tmpA;
            else if (tmpA == NULL){
                tmpA = headB;
                tmpB = tmpB->next;
            }else if (tmpB == NULL){
                tmpB = headA;
                tmpA = tmpA -> next;
            }else{
                tmpA = tmpA -> next;
                tmpB = tmpB -> next;
            }
            
        }   
        return NULL;
    }       
};   

心态炸了心态炸了。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值