Leetcode 160 寻找两链表的交叉节点

问题:

160. Intersection of Two Linked Lists

思想:

解法一:
  第一遍循环,找出两个链表的长度差N
  第二遍循环,长链表先走N步,然后同时移动,判断是否有相同节点

解法二:

  链表到尾部后,跳到另一个链表的头部, 相遇点即为intersection points.

解释:

  • 保持两个指针pA和pB分别在A和B的头部初始化。然后让他们一次遍历列表,一个节点。
  • 当pA到达列表的末尾时,然后将其重定向到B的头部(是的,B,那是正确的)。类似地,当pB到达列表的末尾时,重定向到A的头部。
  • 如果在任何点pA满足pB,则pA / pB是交点节点。
  • 为了了解上述技巧为什么会起作用,请考虑以下两个列表:A = {1,3,5,7,9,11}和B = {2,4,9,11},它们在节点'9 '。由于B.length(= 4)<A.length(= 6),pB将首先到达合并列表的末尾,因为pB正好穿过2个小于pA的节点。通过将pB重定向到头A,将pA重定向到头B,我们现在要求pB比pA更精确地传送2个节点。所以在第二次迭代中,它们保证同时到达交点节点。
  • 如果两个列表有交集,那么它们的最后一个节点必须是相同的。所以当pA / pB到达列表的末尾时,分别记录A / B的最后一个元素。如果最后两个元素不一样,那么这两个列表就没有交集。

方法:两个指针法。
注意点:下一个地址可能为NULL;链表长度不同/相同。
自己的C++代码:
class Solution {
public:  
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode *A=headA;
        ListNode *B=headB;
        
        if (!A||!B)
            return NULL;
        //获取节点差值N
       int A_count=0;
       int B_count=0;
        while (A||B)
        {
            if (A&&B)
            {
                A=A->next;
                A_count++; 
                B=B->next;
                B_count++;
            }
            
            if (A && !B)
            {
               A=A->next;
               A_count++; 
            }
            if (!A && B)
            {
                B=B->next;
                B_count++;
            }
        }
        
       int N=abs(A_count-B_count);
        
        A=headA;
        B=headB;
        if (N==0)
        {
            while(A&&B)
        {
            if (A!=B)
            {
                A=A->next;
                B=B->next;
            }
            else
            return A;
        }
            return NULL;
        }
        
        if (N > 0)
        {
        if(A_count > B_count)
        {
            for(int i=1;i<=N;i++)
                A=A->next;
        }else
        {
            for(int i=1;i<=N;i++)
                B=B->next;
        }
        
        while(A&&B)
        {
            if (A!=B)
            {
                A=A->next;
                B=B->next;
            }
            else
            return A;
        }
         return NULL;
        }
    }
};

优化代码:
public class Solution {  
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {  
        if(headA==null || headB==null) return null;  
          
        ListNode p = headA;  
        ListNode q = headB;  
        int pcount = 0;  
        int qcount = 0;  
        while(p.next != null || q.next != null) {  
            if(p == q) return p;  
            if(p.next != null) p = p.next; else ++qcount;  
            if(q.next != null) q = q.next; else ++pcount;  
        }  
        if(p != q) return null;  
        p = headA;  
        q = headB;  
        while(pcount-- != 0) {  
            p = p.next;  
        }  
          
        while(qcount-- != 0) {  
            q = q.next;  
        }  
          
        while(p != q) {  
            p = p.next;  
            q = q.next;  
        }  
        return p;  
    }  
}  

解法二:
public class Solution {  
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {  
        if(headA==null || headB==null) return null;  
          
        ListNode p = headA;  
        ListNode q = headB;  
        if(p == q) return p;          
        while(p!=null && q!=null) {  
            p = p.next;  
            q = q.next;  
        }  
          
        if(p==null) p = headB; else q = headA;  
          
        while(p!=null && q!=null) {  
            p = p.next;  
            q = q.next;  
        }  
  
        if(p==null) p = headB; else q = headA;  
  
        while(p!=null && q!=null) {  
            if(p==q) return p;  
            p = p.next;  
            q = q.next;  
        }  
        return null;  
    }  
}  


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值