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.
2.双指针法.首先对其中一个链表头尾连接.那么问题就变成了看另一个链表是否存在环的问题了.但这种方法改变了原本链表的结构,需要在最后对其还原;
3.先计算两个链表的长度差,然后对长链表头结点开始移动长度差长的结点,找到位置对应的结点.然后逐个比较是否相等;
#include<iostream>
#include<vector>
#include<set>
using namespace std;
//Definition for singly - linked list.
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
//解法一: 哈希 Submission Result: Memory Limit Exceeded
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
set<ListNode*>NodeSet;
for (; headA != NULL;headA = headA->next)
NodeSet.insert(headA);
while (headB!=NULL)
{
if (NodeSet.count(headB))
return headB;
headB = headB->next;
}
return NULL;
}
//解法二:双指针 缺点:题目要求不改变原本链表结构,因此需要在输出结果前将改变的链表还原
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB)
{
if (headA == NULL)
return NULL;
ListNode*TmpHeadA = headA;
while (TmpHeadA->next != NULL)
TmpHeadA = TmpHeadA->next;
TmpHeadA->next = headA;
if (headB == NULL || headB->next == NULL || headB->next->next == NULL){
TmpHeadA->next = NULL;
return NULL;
}
ListNode*SlowNode = headB->next;
ListNode*FastNode = headB->next->next;
while (FastNode->next != NULL && FastNode->next->next!=NULL && FastNode != SlowNode){
SlowNode = SlowNode->next;
FastNode = FastNode->next->next;
}
if (FastNode->next == NULL || FastNode->next->next == NULL){
TmpHeadA->next = NULL;
return NULL;
}
else{
ListNode*Tmp_HeadB = headB;
while (Tmp_HeadB!=SlowNode)
{
Tmp_HeadB = Tmp_HeadB->next;
SlowNode = SlowNode->next;
}
TmpHeadA->next = NULL;
return SlowNode;
}
}
//解法三:先计算两个链表的长度差,从对应点开始逐个比较
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB)
{
ListNode*TmpHeadA = headA;
ListNode*TmpHeadB = headB;
int LenListA = 0;
int LenListB = 0;
for (; TmpHeadA != NULL; TmpHeadA = TmpHeadA->next, ++LenListA){}
for (; TmpHeadB != NULL; TmpHeadB = TmpHeadB->next, ++LenListB){}
int LenDifference = LenListA - LenListB;
TmpHeadA = headA;
TmpHeadB = headB;
for (int i = 0; i < abs(LenDifference);++i)
{
if (LenDifference>0)
TmpHeadA = TmpHeadA->next;
else if (LenDifference < 0)
TmpHeadB = TmpHeadB->next;
}
while (TmpHeadA!=NULL&&TmpHeadB!=NULL)
{
if (TmpHeadA == TmpHeadB)
return TmpHeadA;
TmpHeadA = TmpHeadA->next;
TmpHeadB = TmpHeadB->next;
}
return NULL;
}