链表的使用

可以用来找出两个链表的交点

题目 力扣160

核心思想

设 A 的长度为 a + c,B 的长度为 b + c,其中 c 为尾部公共部分长度,
可知 a + c + b = b + c + a。

当访问 A 链表的指针访问到链表尾部时,令它从链表 B 的头部开始访问链表 B;
同样地,当访问 B 链表的指针访问到链表尾部时,令它从链表 A 的头部开始访问链表 A。
这样就能控制访问 A 和 B 两个链表的指针能同时访问到交点。

如果不存在交点,那么 a + b = b + a  他们最后的结果都是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 *a = headA;
        ListNode *b = headB;
        while(a != b)
        {
            a = a == NULL? headB : a->next;
            b = b == NULL? headA : b->next;
        }
        return b;
        
    }

};

为什么要用中间变量来遍历链表呢? 而不是 

 while(headA != headB)
        {
            headA = headA == NULL? headB : headA->next;
            headB = headB == NULL? headA : headB->next;
        }
        return headB;
当然,我将提供一个特例来说明为什么直接在头指针`headA`和`headB`上操作可能导致错误。
考虑以下两个链表:

```
链表A: 1 -> 2 -> 3
                 \
                  5 -> 6 -> 7
                 /
链表B:    4 -> 5
```

这两个链表在节点5处相交。我们来看看按照您提供的代码逻辑会发生什么:

1. 开始时,`headA`指向1,`headB`指向4。
2. 没有立即找到交点,所以进入循环。`headA`变为2,`headB`变为5。
3. `headA`变为3,`headB`变为6。
4. `headA`变为5,`headB`变为7。
5. `headA`变为6,`headB`因为`headB == NULL`,按照您的代码,
应该变为`headA`,但这时`headA`还没有更新为`NULL`,
所以`headB`实际上会跳到6的下一个节点,即7的下一个节点,这里出现了逻辑错误。

在第5步中,您的代码逻辑就已经出现了问题,因为`headB`应该跳转到链表A的头部,
但是由于`headA`和`headB`的更新是同时进行的,
`headB = headB == NULL ? headA : headB->next;`
这行代码在`headB`需要跳转到链表A的头部时,并不能正确执行,
因为此时`headA`不是`NULL`,而是链表A中的某个有效节点。

正确的逻辑是,在任一指针(`headA`或`headB`)达到其链表末尾时,
将其重定向到另一个链表的头部,而不是立即重定向到当前链表的下一个节点。
这样,两个指针最终将在第二次遍历时在交点相遇,
或者如果没有交点,它们会同时到达各自链表的末尾(`NULL`),从而结束循环。

因此,使用两个独立的指针变量(如`pointerA`和`pointerB`)是保证逻辑正确性的关键。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值