HOT31-K个一组翻转链表

news2024/11/24 10:41:22

    leetcode原题链接:K个一组翻转链表

题目描述

       给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。

k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

示例 1:

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

示例 2:

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

提示:

  • 链表中的节点数目为 n
  • 1 <= k <= n <= 5000
  • 0 <= Node.val <= 1000

 解题方法:细节决定成败。其实链表的题没有难想到的题,注意还是体现在细节上,通常反转链表最容易造成的问题是链表反转的顺序不对造成链表断链。本题解题主要思路如下:

第1步: 确定待反转区间。假设本次待反转区间为为[p_khead, p_ktail], pre保存p_khead的前一个节点;

第2步:对反转区间做反转。反转[p_khead, p_ktail],用p_k_next保存p_ktail的下一个节点,这样有pre和p_k_next就可以保证[p_khead, p_ktail]翻转后能正常连接上。这里要特别注意循环的终止条件是while(pre != p_ktail),原因可以看下代码备注。

第3步:对反转后的区间进行连接,防止断链路。

第4步:更新pre, p1和p2的位置

C++代码

#include <iostream>
#include <memory> // std::shared_ptr
#include <utility> // std::pair
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        if (!head) {
            return nullptr;
        }
        std::shared_ptr<ListNode> dummy_node(new ListNode(0));
        if (!dummy_node) {
            return nullptr;
        }
        dummy_node->next = head;
        ListNode *pre = dummy_node.get();//保留反转区间的前一个位置
        if (!pre) {
            return nullptr;
        }
        //构建长度为k的区间[p1, p2], pre->p1->p2
        ListNode *p_ktail = pre->next; 
        ListNode *p_khead = p_ktail;
        while (p_ktail) {
            //第1步: 确定反转区间
            for (int i = 0; i < k - 1; i++) { //[p1, p2],p2向前走k-1
                if (!p_ktail) {
                    return dummy_node->next;
                }
                p_ktail =p_ktail->next;
            }
            // 第2步:对反转区间做反转
            if (!p_ktail) {
                return dummy_node->next;
            }
            auto p_k_next = p_ktail->next; //保存翻转前的反转tail的下一个节点
            const auto& res_pair = reverse_sec(p_khead, p_ktail); //返回翻转后的{新头,新尾} 
            // 第3步:对反转后的区间进行连接,防止断链路
            auto new_khead = res_pair.first; 
            auto new_ktail = res_pair.second;
            if (!new_ktail) {
                return dummy_node->next;
            }
            pre->next = new_khead;
            new_ktail->next = p_k_next;
            // 第4步:更新pre, p1和p2的位置
            pre = new_ktail;
            p_khead = pre->next;
            p_ktail = p_khead;
        }
        return dummy_node->next;
    }

    std::pair<ListNode*, ListNode*> reverse_sec(ListNode*phead, ListNode* ptail) {
        ListNode* pre = nullptr;
        ListNode* p = phead;
        //while (p && p != ptail->next) {
        // 特别注意:
        // 这里容易错写成while(p != tail->next),显然是错误的.
        // 原因是tail对应的元素翻转后,tail->next不再指向原来的next,而是指向翻转后的next
        // 除非提前将tail->next在循环外保存,例如:
        // Node* tail_next = tail->next;
        while (pre != ptail) { // 这里容易错写成p != tail->next******本题代码核心,多想想原因
            ListNode* next = p->next;
            p->next = pre;
            pre = p;//更新后继指针
            p = next;//更新前驱指针
        }
        return {ptail, phead};
    }
};

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

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

相关文章

html实现酷炫好看的个人介绍主页(附源码)

文章目录 1.设计来源1.1 主界面1.2 我的简介界面1.3 教育经历界面1.4 我的源码界面1.5 我的相册界面1.6 朋友评价界面1.7 热门文章界面1.8 联系我界面 2.效果和源码2.1 动态效果2.2 源代码2.3 代码目录 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csd…

vue3使用高德地图实现点击获取经纬度以及搜索功能

话不多说直接上干活 在此之前你需要有高德地图的 key&#xff0c;这个自己去申请即可 1&#xff0c;首先需要在终端安装 npm i amap/amap-jsapi-loader --save 2&#xff0c;准备一个容器 <template><div id"container"></div> </templat…

Python 识别拼图验证码

需要识别的某易易盾验证码如下: 识别过程也是非常简单,使用现成的拼图库就行,本文记录一下使用心得(其实也没啥心得,开箱即用,太简单了): 首先,下载gaps拼图库 Install requirements: $ pip install -r requirements.txt $ sudo apt-get install python-tkInstall …

爱奇艺数据湖实战-广告数据湖应用

01 背景 广告数据主要包括效果、品牌和ADX等广告形式的请求和投放链路中产出的一系列日志&#xff0c;经过处理后&#xff0c;用于算法模型训练、广告运营分析、广告投放决策等场景。广告业务对数据的时效性、准确性以及查询性能要求较高。目前&#xff0c;广告数据链路整体采用…

【C语言扫雷的显微镜级别讲述】

C语言扫雷的显微镜级别讲述 分析 很久之前写过这个 现在做一个详细复述从源头出发 首先我们想写扫雷 最基本的框架 1&#xff08;外部&#xff09;.这个游戏可以玩完之后再玩一次 2.&#xff08;内部&#xff09;首先是要创建一个游戏场地 3.&#xff08;内部&#xff09; 电…

Set 集合

1:特点 无序&#xff1a;存取顺序不一致不重复&#xff1a;可以去除重复无索引&#xff1a;不能使用普通for循环遍历&#xff0c;也不能通过索引来获取元素 2&#xff1a;实现类特点 HashSet&#xff1a; 无序&#xff0c;不重复&#xff0c;无索引LinkedHashSet&#xff1a…

Python3 实例(三) | 菜鸟教程(二十一)

目录 一、Python 二分查找 二、Python 线性查找 三、Python 插入排序 四、Python 快速排序 五、Python 选择排序 六、Python 冒泡排序 七、Python 归并排序 一、Python 二分查找 &#xff08;一&#xff09;二分搜索是一种在有序数组中查找某一特定元素的搜索算法。 &a…

手写map

目录 背景过程简介手写HashMap4、put方法5、get方法5、remove方法 总结 背景 让我们来了解一下HashMap吧 过程 简介 HashMap是Java中一中非常常用的数据结构&#xff0c;也基本是面试中的“必考题”。它实现了基于“K-V”形式的键值对的高效存取。JDK1.7之前&#xff0c;Ha…

Docker容器的tomcat安装后访问报404页面的解决办法

上次我们创建的tomcat容器访问的时候是404页面,是因为高版本的并没有把默认的页面放到webapps目录下,这时,就需要我们登录创建的tomcat容器了 登录tomcat容器: docker exec -it my_tomcat /bin/bash 查看当前目录: ls 将webapp.dist下的默认页面复制到webapps目录下: cp …

unity3d:YooAsset零冗余构建Assetbundle代码分析

BuildAssetInfo构建asset信息 1.每个收集器下asset会构建出BuildAssetInfo&#xff0c;这种asset是没有冗余&#xff0c;只有依赖列表 2.每个依赖asset会构建出BuildAssetInfo&#xff0c;会记录将要打入的bundle列表 依赖的Asset列表 这个asset依赖的其他asset列表&#xf…

Tree 树结构

Case 1st 最少的摄像头——亚马逊面试问题 给定一个二叉树&#xff0c;我们在树的节点上安装摄像头。 节点上的每个摄像机都可以监视其父级、自身及其直接子级。 计算监视树的所有节点所需的最小摄像机数。 例&#xff1a; Input: [0,0,null,0,0]Output: 1Explanation: One cam…

asp.net宠物购物商城系统MyPetShop

asp.net宠物购物商城系统 在线购物网站&#xff0c;电子商务系统 主要技术&#xff1a; 基于asp.net架构和sql server数据库 功能模块&#xff1a; 用户可以购买宠物&#xff0c;查看订单记录 修改密码等 运行环境&#xff1a; 运行需vs2013或者以上版本&#xff0c;sql serv…

183 · 木材加工

链接&#xff1a;LintCode 炼码 - ChatGPT&#xff01;更高效的学习体验&#xff01; 题解&#xff1a;九章算法 - 帮助更多程序员找到好工作&#xff0c;硅谷顶尖IT企业工程师实时在线授课为你传授面试技巧 class Solution { public:/*** param l: Given n pieces of wood wi…

Java8 Stream详解

Stream类继承关系 前置知识 Spliterator接口使用 Spliterator是在java 8引入的一个接口&#xff0c;它通常和stream一起使用&#xff0c;用来遍历和分割序列。 只要用到stream的地方都需要Spliterator&#xff0c;比如List&#xff0c;Collection&#xff0c;IO channel等等…

大语言模型的百家齐放

基础语言模型 概念 基础语言模型是指只在大规模文本语料中进行了预训练的模型&#xff0c;未经过指令和下游任务微调、以及人类反馈等任何对齐优化。 如何理解 只包含纯粹的语言表示能力,没有指导性或特定目标。 只在大量无标注文本上进行无监督预训练,用于学习语言表示。 …

unity制作手游fps僵尸游戏

文章目录 介绍制作基本UI枚举控制角色移动切枪、设置音效、设置子弹威力、设置子弹时间间隔、换弹准星控制射击僵尸动画、血条设置导航 介绍 利用协程、枚举、动画器、导航等知识点。 实现移动、切枪、换弹、射击、僵尸追踪、攻击。 制作基本UI 制作人类血条、僵尸血条、移动按…

百度智能车竞赛丝绸之路1——智能车设计与编程实现控制

百度智能车竞赛丝绸之路1——智能车设计与编程实现控制 百度智能车竞赛丝绸之路2——手柄控制 一、项目简介 本项目现已基于鲸鱼机器人开发套件对其整体外形进行设计&#xff0c;并且对应于实习内容——以“丝绸之路”为题&#xff0c;对机器人各个功能与机器人结构部分进行相…

【几何数学】【Python】【C++】判断两条线段是否相交,若相交则求出交点坐标

判断线段是否相交的办法&#xff08;使用了向量叉积的方法&#xff09;&#xff1a; 首先&#xff0c;通过给定的线段端点坐标p1、p2、p3和p4构建了四个向量v1、v2、v3和v4&#xff1a; v1表示从p1指向p2的向量&#xff0c;其分量为[p2[0] - p1[0], p2[1] - p1[1]]。 v2表示从…

Camtasia Studio2023标准版屏幕录制和视频剪辑软件

Camtasia Studio2023提供了强大的屏幕录像、视频的剪辑和编辑、视频菜单制作、视频剧场和视频播放功能等。它能在任何颜色模式下轻松地记录屏幕动作&#xff0c;包括影像、音效、鼠标移动的轨迹&#xff0c;解说声音等等&#xff0c;另外&#xff0c;它还具有及时播放和编辑压缩…

[前端]JS——join()与split()的使用

Array.join():数组转换为字符串,"()"里元素指定数组转为字符串用什么串联&#xff0c;默认为空。 Array.join()的使用&#xff1a; <script>let arr[1,2,3,4]console.log("arr未转换前:",arr,typeof(arr));console.log("arr使用join():"…