20.4.21 相交链表 简单 160
时间复杂度O(n),空间复杂度O(1)
题目
编写一个程序,找到两个单链表相交的起始节点。
注意:
如果两个链表没有交点,返回 null.
在返回结果后,两个链表仍须保持原有的结构。
可假定整个链表结构中没有循环。
程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。
解题、代码思路
- 沿着两个链表走一遍,统计多余的链的长度;
- 长的链先走统计出来的长度,剩下的两条链长度相等,再找结点;
- 看了一些讨论和题解,震惊了,原来可以用双指针分两次循环的(但是是用一个while就行了,条件是两个指针不相同),第一次循环,把两个链表的结尾分别连去对方的头部,再开始第二次循环,若有交点第二次循环必定会相遇,因为1+3==3+1。
代码
/**
* 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) {
if(headA==NULL) return headA;
if(headB==NULL) return headB;
ListNode *currA=headA, *currB=headB;
int countA=0;
int countB=0;
while(currA!=NULL||currB!=NULL){
if(currA!=NULL){
currA=currA->next;
}
if(currB!=NULL){
currB=currB->next;
}
if(currB==NULL && currA!=NULL) countA++;
if(currA==NULL && currB!=NULL) countB++;
}
currA=headA;
currB=headB;
while(countA){
currA=currA->next;
countA--;
}
while(countB){
currB=currB->next;
countB--;
}
while(currA!=NULL){
if(currA==currB) break;
currA=currA->next;
currB=currB->next;
}
return currA;
}
};