题目描述:
给你两个单链表的头节点 headA
和 headB
,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null
。
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
思路:
由于两个链表的长度不同,如果单独遍历每个链表,可能需要遍历很多遍才能找到交点或NULL。因此需要一个更简便的方法使得两个链表能够更快的定位到同一位置。
考虑:
- 假设相交部分长度为c,链表A、B剩余部分为a、b
- 则链表A长度 = a+c,链表B长度 = b + c
- 很显然只要处理好a和b,就能很快找到交叉点
- 对于a,b,c来说,有等式 a+c+b = b+c+a
有了这个等式,其实就茅塞顿开了:
- 设立一个指针p1从链表A开始遍历,另一个指针p2从链表B开始遍历
- p1到链表A尾部时,跳转到链表B的头部开始遍历
- p2同理
- 若链表A和B有交点,则能够找到
- 若链表不相交,则每个指针都将分别遍历完链表A和B 并到达链表尾部,指向NULL。
从上面的思路,就可以得到代码:
ListNode* getIntersectionNode(ListNode* headA,ListNode* headB){
if(!headA || !headB){return NULL;}
ListNode* p1 = headA, *p2 = headB;
// 如果相交,p1 == p2
// 如果不想交,p1 == p2 == NULL
while(p1 != p2){
// p1 == NULL时,到达链表A尾部,重新定位到链表B
p1 = (p1 == NULL ? headB : p1->next);
p2 = (p2 == NULL ? headA : p2->next);
}
return p1;
}
看着很简单!
实际一点都不会...