问题:
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;
}
}