首页 > 其他分享 >链表应用 II

链表应用 II

时间:2023-04-12 23:36:59浏览次数:45  
标签:II 指向 next 链表 tail 应用 倒序 节点

目录

链表应用 II

应用2:Leetcode.25

题目

25. K 个一组翻转链表

输入:\(head = [1,2,3,4,5]\), \(k = 2\)
输出:\([2,1,4,3,5]\)

分析

这里,我们以前面题目中的用例,来说明算法的步骤。

为了避免讨论边界条件,这里,我们使用一个 \(dummy\) 节点指向 \(head\)。

首先,使用三个指针用于遍历主链表时记录子链表在主链表中的位置:

  • \(P_0\) :记录子链表的首节点的前一个节点;

  • \(P_1\) 记录子链表的首节点;

  • \(tail\) 记录子链表的尾节点。

然后,我们遍历主链表,当tail向后移动k步之后,tail所指的元素就是子链表的尾节点,如下图所示:

image

image

image

此时,\(P_1\) 记录子链表的首节点 \(1\),\(tail\) 指向待倒序的子链表的尾节点 \(2\),同时,用 \(post\) 指针记录子链表的下一个节点:

image

然后,我们对子链表进行倒序,我们定义一个两个指针:

  • \(P_3\) 记录子链表的当前节点的前一个节点;

  • \(P_4\) 记录子链表的当前节点;

对子链表进行倒序操作:

image

image

image

image

image

image

子链表倒序的终止条件是 \(P_3\) 移动到子链表的 \(tail\) 节点;

image

倒序完成后,重新将 \(P_1\) 指向倒序后的子链表的首节点 \(2\),\(tail\) 指向倒序后的子链表的尾节点 \(1\),如下图所示:

image

将前驱指针 \(P_0\) 所指向的节点的 \(next\) 指针重新指向新的子链表首节点:

image

将子链表的尾结点的 \(next\) 指针重新指向主链表后驱节点 \(post\):

image

重新指针 \(P_0\) 指向下一个子链表的前驱节点(即当前子链表的尾结点),将 \(P_1\) 指向下一个子链表的首节点:

image

因此,我们可以总结出算法步骤如下:

  • 使用一个指针 \(tail\),先让它指向 \(dummy\) 节点,并用它来遍历主链表,使用如下四个指针,记录子链表在主链表中的位置:

    • \(P_0\):前驱指针,用于记录子链表首节点的前一个节点;

    • \(P_1\):记录子链表的首节点;

    • \(tail\):记录子链表的尾节点;

    • \(post\):后驱指针,用于记录子链表尾节点的后一个节点;

  • 指针 \(tail\) 每移动 \(k\) 步:

    • 对 \(P_1\) 至 \(tail\) 所在的子链表进行倒序操作;

    • 然后,重新将 \(tail\) 指向倒序后的子链表尾节点,将 \(head\) 指向倒序后的子链表首节点;

    • 将倒序后的子链表重新接入主链表,即:

      • 将前驱节点 \(P_0\) 的 \(next\) 指针指向的节点指向倒序后的子链表头节点 \(P1\);

      • 将倒序后的子链表尾节点 \(tail\) 的 \(next\) 指针指向的节点指向后驱节点 \(post\);

    • 重新将 \(P_0\) 指向当前子链表的尾节点 \(tail\),即下一个子链表的前驱节点;

    • 重新将 \(P_1\) 指向当前子链表的尾节点 \(tail\) 的下一个节点,即下一个子链表的头节点;

  • 若指针 \(tail\) 移动的步数小于 \(k\) 步,则直接返回;

代码实现

from typing import Optional


class ListNode:
    def __init__(self, val=0, _next=None):
        self.val = val
        self.next = _next


class Solution:
    def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
        dummy = ListNode(0)
        dummy.next = head
        # p0指向子链表的前一个节点
        p0 = dummy
        # p1指向子链表的首节点
        p1 = head
        while p1:
            tail = p0
            # 查看剩余部分长度是否大于等于 k
            for i in range(k):
                tail = tail.next
                if not tail:
                    return dummy.next

            post = tail.next
            # 对子链表倒序,并使p1指向将新的头节点,tail指向新的尾结点
            p1, tail = self.reverse(p1, tail)

            # 把子链表重新接回原链表
            p0.next = p1
            tail.next = post

            # p0指向当前子链表的尾结点(即下一个子链表的前一个节点)
            p0 = tail
            # p1指向下一个子链表的首节点
            p1 = tail.next

        return dummy.next

    def reverse(self, head: Optional[ListNode], tail: Optional[ListNode]):
        p1 = None
        p2 = head
        while p1 != tail:
            temp = p2.next
            p2.next = p1
            p1 = p2
            p2 = temp

        return tail, head

标签:II,指向,next,链表,tail,应用,倒序,节点
From: https://www.cnblogs.com/larry1024/p/17311327.html

相关文章

  • AWS上DevOps实验(三)--- 使用Terraform创建Web应用基础架构
    从本文档起,作者计划在AWS上做一系列DevOps/IaC相关实验,本文是第三篇,使用Terraform创建Web应用基础架构。本次实验架构图本次实验架构图如下:Terraform代码本次代码可以从下载代码结构如下:文档如下:$lltotal52-rw-r--r--1ec2-userec2-user3201Mar603:22appser......
  • 【LeeCode】213. 打家劫舍 II
    【题目描述】你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。给定一个代表每个房......
  • 多线程应用案例
    需求解析一个Excel中多个sheet的数据,那么此时就可以考虑使用多线程,每个线程解析一个sheet中的数据,然后等待所有的sheet数据解析完成后,再把数据入库在这个需求中,要实现主线程等待所有现场完成shee数据解析操作,第一种方案:采用join()方法publicclassMyJoinTest{publicstaticvoid......
  • mybatis全局变量 (mybatis.configuration.variables) 的应用
    mybatis.configuration.variables是一个可自定义的全局变量:在application.yml中定义:mybatis:mapper-locations:classpath:mapper/*.xmltype-aliases-package:com.example.entityconfiguration:variables:dbtype:mysqlmapper.xml中的使用:<!--更新......
  • JavaWeb中Servlet、web应用和web站点的路径细节("/"究竟代表着什么)
    JavaWeb中Servlet、web应用和web站点的路径细节("/"究竟代表着什么) 1开门见山新建一个tomcatweb项目,配置tomcat的虚拟目录,取默认值(/项目名_war_exploded)那么如果你的tomcat的默认站点(即http://localhost:8080)没有更改的话,这个项目的两个重要的根目录就出来了web站点根目......
  • 通过UIApplicationMain实现应用内多种事件拦截
    简介UIApplicationMain大家并不陌生,因为在通过XCode建立iOS的Ojective-C工程时肯定会看到。新建的main.m文件长这样:intmain(intargc,char*argv[]){NSString*appDelegateClassName;@autoreleasepool{appDelegateClassName=NSStringFromClas......
  • MBI5253GFN-A专为LED视频应用而设计的16通道PWM恒流LED驱动器芯片
    MBI5253GFN-A是为使用内部脉宽调制(PWM)控制的LED视频应用而设计的,具有可选择的14位/13位色深。MBI5253具有一个16位移位寄存器,它将串行输入数据转换为输出端口的每个像素灰度。16个调节电流端口设计用于提供均匀和恒定的电流接收器,以驱动具有广泛VF变化范围的LED。输出电流可以通过......
  • 在电子文档管理系统中应用鱼群算法的优势
    鱼群算法是一种基于自然界中鱼群行为的计算机算法,可以用于优化问题的解决。在电子文档管理系统中,鱼群算法可以用来管理和优化文档的检索和分类。 通过鱼群算法,可以将文档分为不同的群体,并对不同群体的文档进行分类和管理。例如,可以对相似的文档进行聚类,以方便用户检索和浏览。此外......
  • .net 6 MVC项目发布iis 没有views
    解决方案1.安装Nuget包:Install-PackageMicrosoft.AspNetCore.Mvc.Razor.RuntimeCompilation2.在Program.cs中的AddControllersWithViews()之后添加对AddRazorRuntimeCompilation()的调用。也就是builder.Services.AddControllersWithViews().AddRazorRuntimeCompilation();......
  • 【图论之拓扑排序】剑指 Offer II 114. 外星文字典
    剑指OfferII114.外星文字典讲解传送门constintN=26,M=N*N;classSolution{public:inth[N],e[M],ne[M],idx=0;boolst[N];intin[N],cnt=0;//上面三行要写在classSolution内部,不然每次调用不会清空voidadd(inta,intb){......