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.
题意:找出两个单链表的交叉点,样例返回节点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:
/*
看了讨论,发现很聪明的办法:同时遍历A、B,当任意遍历A、B的指针为空后,指向B、A重新开始遍历
(1) 如果有交叉点,则有一刻会指向交叉点
(2) 如果没有交叉点,则有一刻会同时指空
1. a1 -> a2
↘
c1 -> c2 -> c3
↗
b1 -> b2 -> b3
p1遍历次序 :a1 -> a2 -> NU -> c1 -> c2 -> c3 -> NU -> b1 -> b2 -> b3 -> c1
p2遍历次序 :b1 -> b2 -> b3 -> NU -> c1 -> c2 -> c3 -> NU -> a1 -> a2 -> c1
2. a1 -> a2 -> a3
b1 -> b2 -> b3
p1遍历次序 :a1 -> a2 -> a3 -> NULL
p2遍历次序 :b1 -> b2 -> b3 -> NULL
3. a1 -> a2 -> a3
b1 -> b2 -> b3 -> b4
p1遍历次序 :a1 -> a2 -> a3 -> NU -> b1 -> b2 -> b3 -> b4 -> NULL
p2遍历次序 :b1 -> b2 -> b3 -> b4 -> NU -> a1 -> a2 -> a3 -> NULL
4. a1(b1) -> a2(b2) 就是同一条链表
*/
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(headA == NULL || headB == NULL) return NULL;
ListNode* p1 = headA, *p2 = headB;
while(p1 != NULL && p2 != NULL && p1 != p2){
p1 = p1 -> next;
p2 = p2 -> next;
if(p1 == p2) return p1; // 相遇
if(p1 == NULL) p1 = headB;
if(p2 == NULL) p2 = headA;
}
// headA == headB
return p1;
}
};

本文介绍了一种高效算法,用于查找两个单链表的首个交叉节点。该算法能在O(n)时间内完成,并仅使用O(1)额外空间,适用于无环链表结构。
588

被折叠的 条评论
为什么被折叠?



