题目描述
编写一个程序,找到两个单链表相交的起始节点。
例如,下面的两个链表:
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
在节点 c1 开始相交。
注意:
- 如果两个链表没有交点,返回 null.
- 在返回结果后,两个链表仍须保持原有的结构。
- 可假定整个链表结构中没有循环。
- 程序尽量满足 O(n) 时间复杂度,且仅用 O(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) {
int lenA = 0, lenB = 0;
ListNode* a = headA;
ListNode* b = headB;
int flag = 0;
while(headA != NULL && headA->next != NULL) {
headA = headA->next;
lenA++;
}
while(headB != NULL &&headB->next != NULL) {
headB = headB->next;
lenB++;
}
int temp = 0;
if(lenA > lenB) {
temp = lenA - lenB;
flag = 1;
} else {
temp = lenB - lenA;
}
while(temp--) {
if(flag == 1) {
a = a->next;
} else {
b = b->next;
}
}
ListNode* res = NULL;
while(a && b) {
if(a == b) {
res = a;
break;
}
a = a->next;
b = b->next;
}
return res;
}
};
用环的思想来做,我们让两条链表分别从各自的开头开始往后遍历,当其中一条遍历到末尾时,我们跳到另一个条链表的开头继续遍历。两个指针最终会相等,
而且只有两种情况,一种情况是在交点处相遇,另一种情况是在各自的末尾的空节点处相等。
/**
* 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||!headB) return NULL;
ListNode *a = headA;
ListNode *b = headB;
while(a!=b){
a = a ? a->next : headB;
b = b ? b->next : headA;
}
return a;
}
};