数据结构与算法----复习Part 8 (链表双指针)

这篇具有很好参考价值的文章主要介绍了数据结构与算法----复习Part 8 (链表双指针)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本系列是算法通关手册LeeCode的学习笔记

算法通关手册(LeetCode) | 算法通关手册(LeetCode) (itcharge.cn)

本系列为自用笔记,如有版权问题,请私聊我删除。

目录

一,双指针简介(Two Pointers)

二,起点不一致的快慢指针

三,步长不一致的快慢指针

判断链表中是否含有环:

四,分离双指针


一,双指针简介(Two Pointers)

        在遍历元素的过程中,使用两个指针进行访问,并通过两个指针的位置与移动的条件,达到解决问题的目的。

        双指针有快慢指针与分离双指针,在链表中时常有环结构,因此方向不同的对撞双指针很少使用,且不够方便。

二,起点不一致的快慢指针

        两个指针从同一侧开始遍历链表,但是两个指针的起点不一样。快指针比慢指针先走 n 步,直到快指针移动到链表尾端为止。

伪代码模板:

slow = head
fast = head

while n:
    fast = fast.next
    n -= 1

while fast:
    fast = fast.next
    slow = slow.next
    

例题:

19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)

        找到倒数第 n 个指针,然后删除;

        即找到某节点 p,p 到链表尾部还有 n 个节点;

        可是使用快慢指针,fast 先走 n 个节点,使fast 领先 slow 指针 n 个节点;

        当 fast 走到链表尾部是, slow 指向将要移除的节点。

        令 slow 开始位置为 head 的前一个节点,则退出循环时,slow 指向移除节点的前一个节点。

class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        dummy = ListNode()
        dummy.next = head
        fast = head
        while n:
            fast = fast.next
            n -= 1
        slow = dummy
        while fast:
            fast = fast.next
            slow = slow.next
        slow.next = slow.next.next
        return dummy.next

        时间复杂度 O(n)

        空间复杂度 O(1)文章来源地址https://www.toymoban.com/news/detail-826590.html

三,步长不一致的快慢指针

        两个指针从同侧开始遍历链表,起点一致但步长不一致,直到 fast 指针满足条件退出。

伪代码模板:

fast = head
slow = head

while fast and fast.next:
    slow = slow.next
    fast = fast.next.next

例题:

 876. 链表的中间结点 - 力扣(LeetCode)

class Solution:
    def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if not head or not head.next:
            return head
        slow = head
        fast = head
        while fast and fast.next:
            fast = fast.next.next
            slow = slow.next
        return slow

        时间复杂度 O(n)

        空间复杂度 O(1)

判断链表中是否含有环:

        Floyd 判环算法是快慢指针的经典应用。

        使用一个步长为 2 的 fast 指针和一个步长为 1 的 slow 指针,同时从起点出发,如果链表中有环,那么他们一定相遇。

        因为在两个指针都进入环后,可以视为在一快一慢跑圈的两个人,速度快的人必定在有限时间内追上速度慢的人,即完成套圈。

        快慢指针想遇后,在相遇位置启动一个新指针 A,在链表的 head 位置启动一个指针B,都以步长为 1 的速度移动,则 A,B指针必定在环的入口处相遇。

        可以通过运算求证:

        设进入环之前的链表长度为 a,环的长度为 L;

        在快慢指针运动中,若 slow 指针移动了 S 距离,则 fast 指针移动了 2S 距离;

        则 2S - S  = S 是快慢指针移动距离的差值;

        又因为 fast 与 slow 在环上相遇了,所以 fast 比 slow 多跑了 整数圈

        可以设 slow 跑了 n 圈,fast 跑了 m 圈,

        如果 slow 与 fast 在 0.6 圈的位置相遇,n = 1.6,m = 5.6

        S = a + n * L

        2 * S = a + m * L

        2 * S - S = S = (m - n)* L

        即,S 是环长 L 的整数倍。

        此时在该位置启动指针 A,在开始位置启动指针 B;

        当 B 走了 a 距离到环的入口位置时,A 走了 S + a 距离;

        因为 S 是 环长 L 的整数倍,所以此时 A,B 指针在环的入口位置相遇。

例题:

141. 环形链表 - 力扣(LeetCode)

class Solution:
    def hasCycle(self, head: Optional[ListNode]) -> bool:
        if not head or not head.next:
            return False
        fast = head.next
        slow = head
        while fast != slow:
            if not fast or not fast.next:
                return False
            fast = fast.next.next
            slow = slow.next
        return True

四,分离双指针

        两个指针分别属于不同的链表,在不同的链表中移动

伪代码模板:

left_1 = list1
left_2 = list2

while left_1 and left_2:
    if 一定条件 1:
        left_1 = left_1.next
        left_2 = left_2.next
    elif 一定条件 2:
        left_1 = left_1.next
    elif 一定条件 3:
        left_2 = left_2.next

例题:

21. 合并两个有序链表 - 力扣(LeetCode)

class Solution:
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        dummy = ListNode()
        cur = dummy
        left = list1
        right = list2
        while left and right:
            if left.val < right.val:
                cur.next = left
                left = left.next
            else:
                cur.next = right
                right = right.next
            cur = cur.next
        if left:
            cur.next = left
        if right:
            cur.next = right
        return dummy.next

        时间复杂度 O(n)

        空间复杂度 O(1)

到了这里,关于数据结构与算法----复习Part 8 (链表双指针)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【算法与数据结构】链表

    链表是由一串节点串联在一起的,链表的每个节点存储两个信息:数据+下一个节点的地址 分清楚两个概念:什么是内存内部,什么是程序内部 内存内部: 信息存储在内存空间里的 程序内部: 通过什么信息,去操作结构 如果想操作链表的话,我们依靠的是程序内部的信息,

    2024年02月03日
    浏览(45)
  • 【数据结构与算法】链表

    对于顺序表存在一些缺陷: 中间/头部的插入删除,时间复杂度为O(N) 。头部插入需要挪动后面的元素 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插

    2023年04月09日
    浏览(48)
  • 02-链表 (数据结构和算法)

    3.1 链表的基本概念 前面我们在学习顺序表时,线性表的顺序存储结构的特点是逻辑关系上相邻的两个数据元素在物理位置上也是相邻的。我们会发现虽然顺序表的查询很快,时间复杂度为O(1),但是增删的效率是比较低的,因为每一次增删操作都伴随着大量的数据元素移动。为

    2024年02月16日
    浏览(46)
  • Python数据结构与算法-数据结构(列表、栈、队列、链表)

    数据结构是指相互之间存在这一种或者多种关系的数据元素的集合和该集合中元素之间的关系组成。 简单来说,数据结构就是设计数据以何种方式组织并存储在计算机中。 比如:列表、集合与字典等都是一种数据结构。 N.Wirth:“程序=数据结构+算法” 数据结构按照其 逻辑结

    2024年02月08日
    浏览(58)
  • 数据结构与算法:双向链表

    朋友们大家好啊,在上节完成单链表的讲解后,我们本篇文章来对 带头循环双向链表进行讲解 单链表中,一个节点存储数据和指向下一个节点的指针,而双向链表除了上述两个内容,还包括了 指向上一个节点的指针 带头的双向链表,是指在双向链表的最前端添加了一个 额

    2024年02月20日
    浏览(51)
  • 【数据结构与算法】双向链表

    作者:旧梦拾遗186 专栏:数据结构成长日记   带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了。 现在我们来通

    2024年02月11日
    浏览(57)
  • 【数据结构和算法】反转链表

    Java基础合集 数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 方法一:迭代(双指针) 2.2 方法二:递归 三、代码 3.1 方法一:迭代(双指针) 3.2 方法二:递归 四、复杂度分析 4.1 方法一:迭代

    2024年01月18日
    浏览(53)
  • 【数据结构和算法】奇偶链表

    Java基础合集 数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 方法一:分离节点后合并 三、代码 3.1 方法一:分离节点后合并 四、复杂度分析 4.1 方法一:分离节点后合并 这是力扣的 328 题,难

    2024年01月20日
    浏览(50)
  • 算法与数据结构之链表

    链表的定义,相信大家都知道,这里就不赘述了只是链表分单向链表和双向链表,废话不多说,直接上代码 链表节点的定义: 打印链表的两种方式: 翻转单向链表:核心思路是先断开连接,再将next指向前继节点,为了避免断开之后,找不到前继节点,需要用一个临时变量记

    2024年02月05日
    浏览(50)
  • 【数据结构与算法】第七章-图【期末复习】

    图:有向图、网,无向图、网。 顶点 边:有向图图称作弧,分弧头弧尾。 依附:边依附点,边和点关联 邻接:点邻接点 度:点关联的边的数目 完全图: 无向: C n 2 C_n^2 C n 2 ​ 条边; 有向: 2 C n 2 2C_n^2 2 C n 2 ​ 条边 连通:若干结点互相可以通信,用手提起一个结点可以顺

    2024年02月01日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包