文章目录
- 1. 题目
- 2. 我的解法:哈希表,空间复杂度 0(n),不符合要求
- 2.1 算法思路
- 2.2 code
- 3. 双指针法:浪漫相遇太秀了
- 3.1 算法思路
- 3.2 code
1. 题目
题目链接:剑指 Offer 52. 两个链表的第一个公共节点
输入两个链表,找出它们的第一个公共节点。
注意:
如果两个链表没有交点,返回 null.
在返回结果后,两个链表仍须保持原有的结构。
可假定整个链表结构中没有循环。
程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。
这里要留意时间复杂度和空间复杂度的要求
2. 我的解法:哈希表,空间复杂度 0(n),不符合要求
2.1 算法思路
判断两个链表是否相交,可以使用哈希集合存储链表节点。
首先遍历链表 headA,并将链表 headA中的每个节点加入哈希集合中。然后遍历链表 headB,对于遍历到的每个节点,判断该节点是否在哈希集合中:
- 如果当前节点不在哈希集合中,则继续遍历下一个节点;
- 如果当前节点在哈希集合中,则后面的节点都在哈希集合中,即从当前节点开始的所有节点都是两个链表的公共节点,因此在链表 headB 中遍历到的第一个在哈希集合中的节点就是两个链表的第一个公共节点,返回该节点。
如果链表 headB 中的所有节点都不在哈希集合中,则两个链表不相交,返回 null
2.2 code
# 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:
hashmap={}
while headA:
hashmap[headA]=headA
headA=headA.next
while headB:
if headB in hashmap:
return headB
headB=headB.next
return None
假设 链表 headA 和 headB 的长度分别为 m 和 n,则时间复杂度为 O(m+n),空间复杂度为 O(m),因为需要使用哈希集合存储链表 headA 中的全部节点。
但题目要求空间复杂度为 O(1),因此改方法不符合要求。
3. 双指针法:浪漫相遇太秀了
算法参考:图解 双指针法,浪漫相遇
3.1 算法思路
两个链表长度分别为 L1+C、L2+C, C为公共部分的长度。
第一个人走了L1+C步后,回到第二个人起点走L2步;第2个人走了L2+C步后,回到第一个人起点走L1步。 当两个人走的步数都为 L1+L2+C 时就两个家伙就相遇了
3.2 code
初级代码:
# 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:
pt1=headA
pt2=headB
while pt1!=pt2:
if pt1:
pt1=pt1.next
else:
pt1=headB
if pt2:
pt2=pt2.next
else:
pt2=headA
return pt1
进阶版代码:
# 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:
pt1=headA
pt2=headB
while pt1!=pt2:
pt1=pt1.next if pt1 else headB
pt2=pt2.next if pt2 else headA
return pt1
这个双指针法实在太秀了,但是这么秀的方法难度是简单 ???