2021/5/20 刷题笔记相交链表以及双指针法

Posted 黑黑白白君

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021/5/20 刷题笔记相交链表以及双指针法相关的知识,希望对你有一定的参考价值。



相交链表

【题目】

编写一个程序,找到两个单链表相交的起始节点。 如下面的两个链表:
在这里插入图片描述
在节点 c1 开始相交。


注意:

  • 如果两个链表没有交点,返回 null.
  • 在返回结果后,两个链表仍须保持原有的结构。
  • 可假定整个链表结构中没有循环。
  • 程序尽量满足 O(n)时间复杂度,且仅用 O(1) 内存。


来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/intersection-of-two-linked-lists
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

【我的方法】

相交意味着共用后面的链表,因此直接从后面相同的长度的节点开始比较。

# 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:
        a=headA
        b=headB
        n=0
        while(a and b):
            a=a.next
            b=b.next
        if(a):
            while(a):
                a=a.next
                n+=1
            b=headA
            a=headB
        else:
            while(b):
                b=b.next
                n+=1
            a=headA
            b=headB
        while(n>0):
            b=b.next
            n-=1
        while(a):
            if a==b:
                return a
            a=a.next
            b=b.next
        return a

执行结果:

  • 执行用时:176 ms, 在所有 Python3 提交中击败了47.61%的用户

  • 内存消耗:29.6 MB, 在所有 Python3 提交中击败了56.89%的用户

双指针法

解题思路:

设「第一个公共节点」为 node ,「链表 headA」的节点数量为 a ,「链表 headB」的节点数量为 b ,「两链表的公共尾部」的节点数量为 cc,则有:

  • 头节点 headA 到 node 前,共有 a - c 个节点;
  • 头节点 headB 到 node 前,共有 b - c 个节点;
    在这里插入图片描述

考虑构建两个节点指针 A​ , B 分别指向两链表头节点 headA , headB ,做如下操作:

  • 指针 A 先遍历完链表 headA ,再开始遍历链表 headB ,当走到 node 时,共走步数为:
    a + (b - c)

  • 指针 B 先遍历完链表 headB ,再开始遍历链表 headA ,当走到 node 时,共走步数为:
    b + (a - c)

如下式所示,此时指针 A , B 重合,并有两种情况:

a + (b - c) = b + (a - c)

  • 若两链表 有 公共尾部 (即 c > 0 ) :指针 A , B 同时指向「第一个公共节点」node 。
  • 若两链表 无 公共尾部 (即 c = 0 ) :指针 A , B 同时指向 null 。

因此返回 A 即可。

复杂度分析:

  • 时间复杂度 O(a + b) : 最差情况下(即 |a - b| = 1 , c = 0),此时需遍历 a + b个节点。
  • 空间复杂度 O(1) : 节点指针 A , B 使用常数大小的额外空间。

参考代码

# 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:
        a=headA
        b=headB
        while(a!=b):
            a=a.next if a else headB
            b=b.next if b else headA
        return a
  • python的三目运算符 x = c if a else b

    #等价于:
    #当 a = True , x =c 
    #当 a = False , x = b
    if a :
    	x = c
    else:
    	x = b
    


【部分内容参考自】

    1. 相交链表(双指针,清晰图解):https://leetcode-cn.com/problems/intersection-of-two-linked-lists/solution/intersection-of-two-linked-lists-shuang-zhi-zhen-l/

以上是关于2021/5/20 刷题笔记相交链表以及双指针法的主要内容,如果未能解决你的问题,请参考以下文章

2021/5/23 刷题笔记三数之和与双指针法

LeetCode刷题总结之双指针法

160. 相交链表

剑指offer链表题的双指针法总结

力扣234. 回文链表 一题五解让你彻底弄懂链表!反转链表法栈法双指针法快慢指针法递归法

刷题9:反转链表