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.
例如下面两个单链表
A: a1 → a2 ↘ c1 → c2 → c3 ↗ B: b1 → b2 → b3从c1开始相交。
注意:
如果两个链表不相交,返回NULL。
两个单链表在函数调用后应当保持它们原本的结构。(即不能采取反转)
你可以假定单链表中不存在环。
你的代码应当只有O(n)的时间复杂度和O(1)的空间复杂度。
同样属于12月的遗留easy题之一,该题的难点在于无法反转单链表,而又无法知道两个链表在重合节点之前分别有多少个节点不相同(还是根本没有重合的节点)。我一开始是想对每一对节点之间做比较,不过那样时间复杂度就到了O(n!)(好像是,没认真算),遂作罢。后来还是看了讨论了的才知道原来还可以把链表剪成一样长度再比较。。。现在觉得我当初脑子是怎么想的才做不出来。。。
/**
* 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 *tempA=headA,*tempB=headB;
if(!headA||!headB) return NULL;
int A_length=1,B_length=1;
while(tempA->next)
{
tempA=tempA->next;
A_length++;
}
while(tempB->next)
{
tempB=tempB->next;
B_length++;
}
tempA=headA;
tempB=headB;
if(A_length>B_length)
{
while(A_length!=B_length)
{
tempA=tempA->next;
A_length--;
}
}
else if(A_length<B_length)
{
while(A_length!=B_length)
{
tempB=tempB->next;
B_length--;
}
}
while(tempA->next)
{
if(tempA==tempB)
return tempA;
tempA=tempA->next;
tempB=tempB->next;
}
if(tempA==tempB)
return tempA;
return NULL;
}
};