冲击大厂算法面试=>链表专题【链表反转之局部反转升级版】

news2024/9/21 2:40:36

目录标题

  • 多重局部反转之K 个一组翻转链表
    • 上代码
    • 题解呀
    • 实在不会的时候记住

多重局部反转之K 个一组翻转链表

在这里插入图片描述

上代码

整个函数通过不断地检查剩余节点数量和进行局部反转,实现了链表的分组反转,最后返回反转后的链表。这种方法有效地利用了额外的 pre 和 cur 指针来跟踪反转过程,避免了复杂的数据结构和额外的空间消耗。

class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        //头节点法
        ListNode newPreHead = new ListNode(-1);
        newPreHead.next = head;

        ListNode pre = newPreHead;
        // 原地反转
        while (true) {
            // 检查剩余节点是否有k个,不足则返回
            ListNode innerCur = pre;
            int i = 0;
            while (i < k) {
                innerCur = innerCur.next;
                i++;
                if (innerCur == null) {
                    return newPreHead.next;
                }
            }

            // 翻转k个节点,操作k-1次就行
            // 1 2 3 -> 2 1 3
            // 目标:反转从 pre.next 开始的 k 个节点
            ListNode cur = pre.next;// 1
            for (int j = 0; j < k - 1; j++) {
                // 在每次循环中,node1 是当前要反转的节点
                ListNode node1 = cur.next;
                // 断开 cur 和 node1 的连接,准备反转 node1
                cur.next = node1.next;
                // 将 node1 插入到 pre 的后面,反转 node1
                node1.next = pre.next;
                // 更新 pre 的 next 指向反转后的 node1
                pre.next = node1;
            }
            // 更新 pre,准备处理下一组节点
            pre = cur;
        }
    }
}

在这里插入图片描述

题解呀

本题的难点在于连续的局部反转
核心代码:

// 翻转k个节点,操作k-1次就行
// 1 2 3 -> 2 1 3
// 目标:反转从 pre.next 开始的 k 个节点
ListNode cur = pre.next;// 1
for (int j = 0; j < k - 1; j++) {
    // 在每次循环中,node1 是当前要反转的节点
    ListNode node1 = cur.next;
    // 断开 cur 和 node1 的连接,准备反转 node1
    cur.next = node1.next;
    // 将 node1 插入到 pre 的后面,反转 node1
    node1.next = pre.next;
    // 更新 pre 的 next 指向反转后的 node1
    pre.next = node1;
}
// 更新 pre,准备处理下一组节点
pre = cur;

举例子说明核心代码

初始链表结构如下:
newPreHead -> 1 -> 2 -> 3 -> 4 -> 5

newPreHead 是虚拟头结点,初始 pre 指向 newPreHead。
cur 指向 1,即当前组的第一个节点。
node1 将在反转过程中表示下一个要反转的节点。
-----------------------------------
第一次反转(k=2)
步骤 1: 初始化 cur 和 node1
newPreHead -> 1 -> 2 -> 3 -> 4 -> 5
   ^         ^     ^
   |         |     |
  pre       cur   node1
-----------------------------------

步骤 2: 断开 cur 和 node1 的连接,准备反转 node1
【cur.next = node1.next;2
newPreHead -> 1 -> - -> 3 -> 4 -> 5
   ^         ^     ^
   |         |     |
  pre       cur   node1
  
-----------------------------------
步骤 3: 将 node1 插入到 pre 后面,反转 node1
【node1.next = pre.next;<-<-<-
              |    |2
newPreHead -> 1 -> - ->3 -> 4 -> 5
   ^         ^     ^
   |         |     |
  pre       cur   node1
  
步骤 4:再次执行【pre.next = node1;| -> -> -> -> -> -> >
   |                   |
   |          <-<-<-   | 
   |          |    |   | 
   |2 < - 
newPreHead    1 -> - ->3 -> 4 -> 5
   ^         ^     ^
   |         |     |
  pre       cur   node1

-----------------------------------
步骤 5: 更新 pre,准备处理下一组节点
【 pre = cur;】
newPreHead -> 2 -> 1 -> 3 -> 4 -> 5
			  	   ^   
			  	   |   
			      cur
			      pre 
此时,pre.next 指向了 2,node1.next 指向了 1,完成了第一次反转。
第二轮初始化就会变成,node1=4成为要反转的点
newPreHead -> 2 -> 1 -> 3 -> 4 -> 5
			  	   ^    ^    ^
			  	   |    |    |   
			      pre  cur  node1
-----------------------------------
直到循环结束

实在不会的时候记住

通过数据结构来简化问题

class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        
        Deque<ListNode> stack = new ArrayDeque<ListNode>();
        ListNode dummy = new ListNode(0);
        ListNode p = dummy;
        while (true) {
            int count = 0;
            ListNode tmp = head;
            //我们把 k 个数压入栈中,然后弹出来的顺序就是翻转的
            while (tmp != null && count < k) {
                stack.add(tmp);
                tmp = tmp.next;
                count++;
            }

            //不相等 说明到最后了 退出
            if (count != k) {
                //不翻转
                p.next = head;
                break;
            }
            
            //栈不为空  翻转
            while (!stack.isEmpty()){
                p.next = stack.pollLast();
                p = p.next;
            }
            
            head = tmp;
        }
        return dummy.next;
    }
}

好用的话就点个赞吧!!!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2103264.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VBA学习(71):Excel VBA 访问带密码保护的Access数据库/用户窗体设置/EXCEL用户+密码登录界面(Access版)

前两天我们分享了一个用户密码登录EXCEL的案例【Excel VBA 用户窗体设置/一步一步代你设计EXCEL用户密码登录界面】&#xff0c;文中提及数据存储在Access中的情况&#xff0c;今天我就来把数据表&#xff08;tb用户&#xff09;移到Access中&#xff0c;修改一下代码&#xff…

使用jmeter压测数据库

写在文章开头 除了wrk以外,jmeter一直是笔者比较喜欢的一个压测工具,从使用场景和功能范围来看,算是一款比较全面且上手快速的压测工具,本文将基于MySQL数据库为读者演示一下如何通过jmeter压测数据库,希望对你有帮助。 Hi,我是 sharkChili ,是个不断在硬核技术上作死的…

FreeRTOS学习笔记—②RTOS的认识(持续更新中)

由于正在学习韦东山大佬的RTOS课程&#xff0c;结合了网上的一些资料&#xff0c;整理记录了下自己的感悟&#xff0c;用于以后自己的回顾。如有不对的地方请各位大佬纠正。 课程链接&#xff1a;https://www.bilibili.com/video/BV1844y1g7ud/?spm_id_from333.337.search-car…

Postman环境变量:简化API测试的利器

引言 在当今快速发展的互联网时代&#xff0c;API&#xff08;应用程序接口&#xff09;的重要性不言而喻。无论是内部系统间的通信还是对外服务的提供&#xff0c;API都扮演着至关重要的角色。然而&#xff0c;在API的开发与测试过程中&#xff0c;经常需要处理各种各样的配置…

Java语言程序设计基础篇_编程练习题**17.21 (十六进制编辑器)

目录 题目&#xff1a;**17.21 (十六进制编辑器) 代码示例 结果展示 题目&#xff1a;**17.21 (十六进制编辑器) 编写一个 GUI 应用程序&#xff0c;让用户在文本域输入一个文件名&#xff0c;然后按回车键&#xff0c;在文本域显示它的十六进制表达形式。用户也可以修改十六…

SEO之网站结构优化(十四-内部链接及权重分配3)

初创企业搭建网站的朋友看1号文章&#xff1b;想学习云计算&#xff0c;怎么入门看2号文章谢谢支持&#xff1a; 1、我给不会敲代码又想搭建网站的人建议 2、“新手上云”能够为你开启探索云世界的第一步 博客&#xff1a;阿幸SEO~探索搜索排名之道 7、锚文字分布及变化 前面…

不可不知的WPF形状(Shape)

在WPF开发中经常需要进行绘制图形&#xff0c;可以利用Shape类型绘制基本的形状&#xff0c;而且Shape派生自FrameworkElement&#xff0c;属于UI元素范畴&#xff0c;可以直接利用XAML进行绘制。本文通过一些简单的小例子&#xff0c;简述如何通过Shape类绘制形状&#xff0c;…

SMB攻击利用之-设置远程mimikatz程序为定时任务流量数据包分析

SMB协议作为windows环境下最为常见的一种协议&#xff0c;在历史上出现过无数的通过SMB协议进行网络攻击利用的案例&#xff0c;包括针对SMB协议本身以及通过SMB协议实施网络攻击。 本文将介绍一种SMB协议的常见利用方式&#xff0c;即通过windows的服务调用将远程主机上的mim…

MySQL数据库安装(详细)—>Mariadb的安装(day21)

该网盘链接有效期为7天&#xff0c;有需要评论区扣我&#xff1a; 通过网盘分享的文件&#xff1a;mariadb-10.3.7-winx64.msi 链接: https://pan.baidu.com/s/1-r_w3NuP8amhIEedmTkWsQ?pwd2ua7 提取码: 2ua7 1 双击打开安装软件 本次安装的是mariaDB&#xff0c;双击打开mar…

【STM32开发】GPIO最全解析及应用实例

目录 【1】GPIO概述 GPIO的基本概念 GPIO的应用 【2】GPIO功能描述 1.IO功能框图 2.知识补充 3.功能详述 浮空输入 上拉输入 下拉输入 模拟输入 推挽输出 开漏输出 复用开漏输出和复用推挽输出 【3】GPIO常用寄存器 相关寄存器介绍 4个32位配置寄存器 2个32位数据寄存器 1个32位…

Linux【1】基础

目录 cd ​编辑 Linux的粘贴是Ctrlshiftv&#xff0c;复制、剪切&#xff1a; pwd打印当前路径 cat 文件目录 读取 ↑ 可以调取之间输过的命令 mv A B 把文件名A改成B #掐头%去尾 touch 文件名 mkdir创建目录​编辑 删除rm 只能删除文件 终端命令格式 帮助 man命…

vant 动态查询下拉菜单(可用)

动态查询item项 <van-form submit"onSubmit" ref"formRef"><Title title"企业信息" title-line title-size"19" class"ml-[18px] mb-[18px]"></Title><van-cell-group inset class"py-[18px]&quo…

springblade-JWT认证缺陷漏洞CVE-2021-44910

漏洞成因 SpringBlade前端通过webpack打包发布的&#xff0c;可以从其中找到app.js获取大量接口 然后直接访问接口&#xff1a;api/blade-log/api/list 直接搜索“请求未授权”&#xff0c;定位到认证文件&#xff1a;springblade/gateway/filter/AuthFilter.java 后面的代码…

【数据分享】2021-2024年我国主要城市逐月轨道交通客运量数据

以地铁为代表的轨道交通是大城市居民的主要交通出行方式之一&#xff0c;轨道交通的客运量数据是评估城市轨道交通系统运行效率、承载能力和服务水平的重要指标。本次我们为大家带来的是2021-2024年我国主要城市的逐月轨道交通客运量数据&#xff01;数据更新到2024年7月份。 …

网络安全之DC-2靶机渗透测试实战

一、靶机环境搭建 1.下载DC-2虚拟机镜像文件&#xff0c;解压后用VM打开。 DC-2镜像&#xff0c;若链接失效&#xff0c;关注公众号 文化仁 回复DC-2获取&#xff0c;或联系我获取https://pan.baidu.com/s/1gVVdEbiTkFUEOpewsn1iRg?pwd2t1j 2.设置DC-2虚拟机的网络适配器为…

redis之缓存淘汰策略

1.查看redis的最大占用内存 使用redis-cli命令连接redis服务端&#xff0c;输入命令&#xff1a;config get maxmemory 输出的值为0&#xff0c;0代表redis的最大占用内存等同于服务器的最大内存。 2.设置redis的最大占用内存 编辑redis的配置文件&#xff0c;并重启redis服务…

C语言基础(三十四)

Win32 API&#xff08;Application Programming Interface&#xff09;是微软Windows操作系统提供的一套底层的应用程序编程接口&#xff0c;允许开发者直接与Windows操作系统交互&#xff0c;创建和管理窗口、图形界面、系统资源等。Win32 API主要用于开发桌面应用程序&#x…

【OpenWrt(2)】编译OpenWrt 的SDK,以linksys e8450 的MT7622 CPU为例

资源 参考 https://downloads.openwrt.org/releases/ 文章目录 资源依赖下载 SDK查询 CPU 信号 解压使用 feed 编译后台运行 依赖 apt-get update apt-get install subversion build-essential libncurses5-dev zlib1g-dev gawk git ccache gettext libssl-dev xsltproc wget…

气膜体育馆空气质量保障:健康运动新选择—轻空间

随着气膜体育馆的广泛应用&#xff0c;人们对其内部空气质量的关注日益增加。许多人担心封闭的气膜结构可能会导致空气流通不畅&#xff0c;进而影响健康。然而&#xff0c;现代气膜体育馆凭借独特的建筑设计、先进的空气净化系统以及良好的通风和换气机制&#xff0c;能够有效…

传统CV算法——边缘算子与图像金字塔算法介绍

边缘算子 图像梯度算子 - Sobel Sobel算子是一种用于边缘检测的图像梯度算子&#xff0c;它通过计算图像亮度的空间梯度来突出显示图像中的边缘。Sobel算子主要识别图像中亮度变化快的区域&#xff0c;这些区域通常对应于边缘。它是通过对图像进行水平和垂直方向的差分运算来…