两个链表的第一个公共节点
题目
输入两个链表,找出它们的第一个公共节点。
- 如果两个链表没有交点,返回 null.
- 在返回结果后,两个链表仍须保持原有的结构。
- 可假定整个链表结构中没有循环。
- 程序尽量满足 O ( n ) O(n) O(n)时间复杂度,且仅用 O ( 1 ) O(1) O(1)内存
思路 快慢指针
(1)先统计两个链表的长度,设置两个指针,长的先走长度差步
(2)接着两个指针同时向后走,相遇时即为所求,如下图
- p1先走到2
- p1和p2分别从2和4开始向后走
- p1和p2在6相遇,即为所求
用双栈,空间复杂度
O
(
n
+
m
)
O(n+m)
O(n+m)
快慢指针空间复杂度
O
(
1
)
O(1)
O(1),时间复杂度
O
(
n
+
m
)
O(n+m)
O(n+m)
**C++ **
/**
* 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==nullptr || headB==nullptr)
return nullptr;
int n=0;
ListNode* p1=headA;
ListNode* p2=headB;
while(p1->next!=nullptr)
{
p1=p1->next;
++n;
}
while(p2->next!=nullptr)
{
p2=p2->next;
--n;
}
if(p1!=p2) //尾节点不同,没有公共节点
return nullptr;
// 把p1改为较长链表的头部
if (n>0)
{
p1 = headA;
p2 = headB;
}
else
{
p1 = headB;
p2 = headA;
}
n = abs(n);
while(n>0)
{
p1 = p1->next;
--n;
}
while(p1!=p2)
{
p1 = p1->next;
p2 = p2->next;
}
return p1;
}
};
python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if headA==None or headB==None:
return None
n = 0
p1, p2 = headA, headB
while p1.next:
p1 = p1.next
n += 1
while p2.next:
p2 = p2.next
n -= 1
if p1 != p2:
return None
if n>0:
p1, p2 = headA, headB
else:
p1, p2 = headB, headA
n = abs(n)
while n:
p1 = p1.next
n -= 1
while p1!=p2:
p1 = p1.next
p2 = p2.next
return p1