【问题描述】
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.
从尾部开始比较,相等则更新rh。否则跳出循环。返回rh即可。
用到了两个栈,来倒序访问list中元素。
时间复杂度:O(n)
空间复杂度:O(n)
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* h1 = headA;
ListNode* h2 = headB;
ListNode* rh=NULL;
stack<ListNode*> prev1;
stack<ListNode*> prev2;
if (h1 == NULL || h2 == NULL)
return NULL;
while (h1 != NULL) {
prev1.push(h1);
h1 = h1->next;
}
while (h2 != NULL) {
prev2.push(h2);
h2 = h2->next;
}
while(!prev1.empty() && !prev2.empty())
{
if(prev1.top()==prev2.top())
{
rh=prev1.top();
prev1.pop();
prev2.pop();
}
else break;
}
return rh;
}
};
第一次一次性写完就提交成功O(∩_∩)O哈哈~
运行时间48ms,击败了90几%的人,不错~不过空间复杂度可以改进下的。
继续改进~
【解答2】
记录两个链表的长度,求长度差,从两个链表所剩长度相等处,开始进行比较。
时间复杂度:O(n)
空间复杂度:O(1)
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* h1 = headA;
ListNode* h2 = headB;
ListNode* rh=NULL;
int len1=0;
int len2=0;
int dist=0;
if (h1 == NULL || h2 == NULL)
return NULL;
for(;h1!=NULL;h1=h1->next)
len1++;
for(;h2!=NULL;h2=h2->next)
len2++;
h1=headA;
h2=headB;
dist=abs(len1-len2);//abs在头文件stdlib.h中,不是math.h
if(len1>=len2)
while(dist!=0)
{
h1=h1->next;
dist--;
}
else
while(dist!=0)
{
h2=h2->next;
dist--;
}
while(h1!=NULL)
{
if(h1->val==h2->val)
{
rh=h1;
break;
}
h1=h1->next;
h2=h2->next;
}
return rh;
}
};
运行时间52ms。
【解答3】
参考LeetCode里这道题的答案3,觉得很精妙,尝试编写。
用双指针,遍历,每次一个元素。当到达一个链表的末尾时,就将该指针指向另一个链表表头。这样其实相当于第二种方法中,从长度相同处开始比较。
此方法使用时候,要认真考虑边界的处理。是判断h1==NULL还是h1->next==NULL,要考虑好。如果写成h1->next的话,你会发现,如果两个链表没有交叉,那这就是个死循环啊!!
时间复杂度:O(n)
空间复杂度:O(1)
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* h1 = headA;
ListNode* h2 = headB;
ListNode* rh=NULL;
if (h1 == NULL || h2 == NULL)
return NULL;
while(h1!=NULL || h2!=NULL)
{
if(h1!=NULL && h2!=NULL && h1->val==h2->val)//最开始忘记检测h1和h2是否为空,导致程序崩溃
{
rh=h1;
break;
}
h1=h1==NULL?headB:h1->next;
h2=h2==NULL?headA:h2->next;
}
return rh;
}
};
代码变短了,逼格提升了,但运行时间为56ms啊~只击败了10几%的人。是因为这个while进来每次都要判断吗?