反转链表相关的练习(上)

news2024/9/28 10:20:36

目录

一、反转链表

二、反转链表 ||

三、两两交换链表中的结点

四、K 个一组翻转链表



一、反转链表

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1

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

输出:[5,4,3,2,1]

示例 2

 输入:head = [1,2]

输出:[2,1]

示例 3

输入:head = []

输出:[]

提示

  • 链表中节点的数目范围是 [0, 5000]

  • -5000 <= Node.val <= 5000

代码实现一

struct ListNode* reverseList(struct ListNode* head)
{
    struct ListNode* pre = NULL;
    struct ListNode* cur = head;
    while (cur != NULL)
    {
        struct ListNode* after = cur->next;
        cur->next = pre;
        pre = cur;
        cur = after;
    }
    return pre;
}

代码实现二(将结点依次头插到新链表中)

struct ListNode* reverseList(struct ListNode* head)
{
    struct ListNode* newhead = NULL;
    struct ListNode* cur = head;
    while (cur != NULL)
    {
        struct ListNode* after = cur->next;
        // 头插
        cur->next = newhead;
        newhead = cur;
        cur = after;
    } 
    return newhead;
}


二、反转链表 ||

给你单链表的头指针 head 和两个整数 leftright ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表

示例 1

 输入:head = [1,2,3,4,5], left = 2, right = 4

输出:[1,4,3,2,5]

示例 2

输入:head = [5], left = 1, right = 1

输出:[5]

提示

  • 链表中节点数目为 n

  • 1 <= n <= 500

  • -500 <= Node.val <= 500

  • 1 <= left <= right <= n

进阶: 你可以使用一趟扫描完成反转吗?

代码实现

struct ListNode* reverseBetween(struct ListNode* head, int left, int right)
{
    struct ListNode* guard = (struct ListNode*)malloc(sizeof(struct ListNode));
    guard->next = head;
    struct ListNode* tmp = guard;
    // 1. 让 tmp 指向第 left - 1 个结点(不包括哨兵位的头结点)
    for (int i = 0; i < left - 1; ++i)
    {
        tmp = tmp->next;
    }
    // 2. 反转从位置 left 到位置 right 的链表结点
    struct ListNode* pre = tmp->next;
    struct ListNode* cur = pre->next;
    for (int i = 0; i < right - left; ++i)
    {
        struct ListNode* after = cur->next;
        cur->next = pre;
        pre = cur;
        cur = after;
    }
    // 经过反转,tmp->next 指向的结点变成了从位置 left 到位置 right 中最后一个结点,
    // 而 pre 指向的结点则变成了第一个结点
    tmp->next->next = cur;  // (1)
    tmp->next = pre;  // (2)
    head = guard->next;
    free(guard);
    return head;
}

图解示例一

 


三、两两交换链表中的结点

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

示例 1

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

输出:[2,1,4,3]

示例 2

输入:head = []

输出:[]

示例 3

输入:head = [1]

输出:[1]

提示

  • 链表中节点的数目在范围 [0, 100]

  • 0 <= Node.val <= 100

代码实现

struct ListNode* swapPairs(struct ListNode* head)
{
    // 创建一个哨兵位的头结点
    struct ListNode* guard = (struct ListNode*)malloc(sizeof(struct ListNode));
    guard->next = head;
    // 交换 tmp 后面的两个结点
    struct ListNode* tmp = guard;
    while (tmp->next && tmp->next->next)
    {
        struct ListNode* node1 = tmp->next;
        struct ListNode* node2 = tmp->next->next;
        tmp->next = node2;  // (1)
        node1->next = node2->next;  // (2)
        node2->next = node1;  // (3)
        // 更新 tmp
        tmp = node1;
    }
    head = guard->next;
    free(guard);
    return head;
}


四、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

代码实现

struct ListNode* reverseKGroup(struct ListNode* head, int k)
{
    struct ListNode* guard = (struct ListNode*)malloc(sizeof(struct ListNode));
    guard->next = head;
    struct ListNode* tmp = guard;
    while (1)
    {
        // 判断剩余长度是否大于或等于 k
        struct ListNode* p = tmp;
        for (int i = 0; p != NULL && i < k; ++i)
        {
            p = p->next;
        }
        if (p == NULL)
        {
            break;
        }
        // 翻转 tmp 后面的 k 个结点
        struct ListNode* pre = tmp->next;
        struct ListNode* cur = pre->next;
        for (int i = 0; i < k - 1; ++i)
        {
            struct ListNode* after = cur->next;
            cur->next = pre;
            pre = cur;
            cur = after;
        }
        // 经过翻转后,tmp->next 指向的结点变成了最后一个结点,
        // 而 pre 指向的结点则变成成了第一个结点
        tmp->next->next = cur;  // (1)
        struct ListNode* last = tmp->next;  // 保存最后一个结点的地址
        tmp->next = pre;  // (2)
        // 更新 tmp
        tmp = last;
    }
    head = guard->next;
    free(guard);
    return head;
}

图解示例二

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

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

相关文章

ip-guardip-guard如何通过准入网关对指定的服务器进行通讯加密保护?

1、准入网关在高级配置设置受保护服务器; WEB管理界面【系统工具】,点击【配置管理】,点击参数设置,进入高级配置界面,输入配置内容即可。 [ControlServer]

使用阈值图修改角色脸部阴影

大家好&#xff0c;我是阿赵。 之前介绍了通过修改模型顶点法线的方法&#xff0c;来解决角色模型脸部光影问题。这里再顺便介绍一下第二种方法&#xff0c;使用阈值图修改角色脸部阴影 一、角色脸部光影的问题 这个问题之前讨论过&#xff0c;由于角色脸部法线复杂&#xff0…

2023年最新交通航线(飞机、高铁)信息数据合集(含经纬度匹配)

中国高铁航线数据库Chinese High-speed Rail and Airline Database&#xff0c;CRAD&#xff09;是一个专门收集和管理航空公司和高铁公司交通航线信息的数据仓库。它包含了航线的起始点、终止点、中转点、飞行时间、票价、座位数、乘客数量、货物数量等信息。 该数据仓库可以运…

Fortinet 发布《2022下半年度全球威胁态势研究报告》,七大发现值得关注

全球网络与安全融合领域领导者Fortinet&#xff08;NASDAQ&#xff1a;FTNT&#xff09;&#xff0c;近日发布《2022 下半年度全球威胁态势研究报告》。报告指出&#xff0c;相对于组织攻击面的不断扩大以及全球威胁态势的持续演进&#xff0c;网络犯罪分子设计、优化技术与战术…

设计模式---单例模式

目录 1 简介 2 实现 3 单例模式的几种实习方式 1. 饿汉式 2. 懒汉式&#xff0c;线程不安全 3. 懒汉式&#xff0c;线程安全 4. 双检锁/双重校验锁(DCL, double-check locking) 5. 登记式/静态内部类 4 单例模式的优缺点 1 简介 单例模式(Singleton Pattern) 是 Java…

React 中五种常见的样式

React 中五种常见的样式策略 React中的样式策略主要有以下几种&#xff1a; 内联样式&#xff1a; 内联样式就是在JSX元素中&#xff0c;直接定义行内的样式&#xff1b;CSS样式表&#xff1a; 这也是我们最常用的样式策略&#xff0c;使用单独的样式表&#xff0c;使用CSS或…

lvgl 笔记 按钮部件 (lv_btn) 和 开关部件 (lv_switch)

按钮基础使用方法&#xff1a; lv_btn 和 lb_obj 使用方法一样&#xff0c;只是外表并不相同&#xff0c;基础创建方法只需一行代码。 lv_obj_t* btn lv_btn_create(lv_scr_act()); 添加大小和位置&#xff1a; lv_obj_t* btn lv_btn_create(lv_scr_act()); lv_obj_set_s…

一个小故障:vTaskGenericNotifyGiveFromISR卡死的解决

平台&#xff1a;gd32f103 freertos V10.4.3 LTS Patch 2 调试的时候发现一个问题&#xff1a; 在中断中使用 vTaskNotifyGiveFromISR(TaskHandle_ToCpu_IIC,NULL); //唤醒任务 但是程序却出现卡死现象&#xff1a; 在vTaskGenericNotifyGiveFromISR函数中。 用调试器看到…

C++ STL:string类的概述及常用接口说明

目录 一. 什么是STL 二. string类的概述 三. string类的常用接口说明 3.1 字符串对象创建相关接口&#xff08;构造函数&#xff09; 3.2 字符串长度和容量相关接口 3.3 字符访问相关接口函数 3.4 字符串删改相关接口函数 3.5 字符查找和子串相关接口函数 3.6 迭代器相…

c++11右值引发的概念

右值引用右值&&左值c11增加了一个新的类型&#xff0c;右值引用&#xff0c;记作&#xff1a;&&左值是指在内存中有明确的地址&#xff0c;我们可以找到这块地址的数据&#xff08;可取地址&#xff09;右值是只提供数据&#xff0c;无法找到地址&#xff08;不…

跨时钟域CDC

https://www.cnblogs.com/icparadigm/p/12794483.html https://www.cnblogs.com/icparadigm/p/12794422.html 亚稳态 是什么 时序逻辑在跳变时&#xff0c;由于异步信号、跨时钟域等原因&#xff0c;不满足setup或hold条件&#xff0c;输出在0和1之间产生振荡。 原因 D触发…

Canny算法原理和应用

Canny算法的原理使用高斯滤波器滤波使用 Sobel 滤波器滤波获得在 x 和 y 方向上的输出&#xff0c;在此基础上求出梯度的强度和梯度的角度edge为边缘强度&#xff0c;tan为梯度方向上图表示的是中心点的梯度向量、方位角以及边缘方向&#xff08;任一点的边缘与梯度向量正交&am…

如何在MySQL 8中实现数据迁移?这里有一个简单易用的方案

文章目录前言一. 致敬IT领域的那些女性二. 进制方式安装MySQL2.1 下载软件包2.2 配置环境&#xff1a;2.2.1 配置yum环境2.2.2 配置安全前的系统环境2.3 开始安装2.4 初始化MySQL2.5 修改配置文件2.6 将MySQL设为服务并启动测试三. MySQL数据迁移总结前言 正好赶上IT女神节&am…

《Linux运维实战:ansible中的变量定义及以及变量的优先级》

一、配置文件优先级 Ansible配置以ini格式存储配置数据&#xff0c;在Ansible中⼏乎所有配置都可以通过Ansible的Playbook或环境变量来重新赋值。在运⾏Ansible命令时&#xff0c;命令将会按照以下顺序查找配置⽂件。 # ⾸先&#xff0c;Ansible命令会检查环境变量&#xff0c…

【node : 无法将“node”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。 最全面有效的解决方案】

执行nodejs文件错误&#xff1a; 这个错误提示通常是由于你的系统无法识别 "node" 命令&#xff0c;可能是由于你没有正确地安装或配置 Node.js 环境变量。 问题描述 ​​​​​​​​​​​​​​ 原因分析&#xff1a; 可能原因包括&#xff1a; 1.Node.js未正确安…

JVM堆与堆调优以及出现OOM如何排查

调优的位置——堆 Heap&#xff0c;一个JVM只有一个堆内存&#xff0c;堆内存的大小是可以调节的。 类加载器读取了类文件后&#xff0c;一般会把什么东西放到堆中?类&#xff0c;方法&#xff0c;常量&#xff0c;变量~&#xff0c;保存我们所有引用类型的真实对象; 堆内存中…

【Linux修炼】15.进程间通信

每一个不曾起舞的日子&#xff0c;都是对生命的辜负。 进程间通信进程间通信一.理解进程间通信1.1 什么是通信1.2 为什么要有通信1.3 如何进行进程间通信二.管道2.1 匿名管道2.2 匿名管道编码部分2.3 管道的特点2.4 如何理解命令行中的管道2.5 进程控制多个子进程三.命名管道3.…

openEuler用户软件仓(EUR)介绍

什么是 EUR EUR(openEuler User Repo)是openEuler社区针对开发者推出的个人软件包托管平台&#xff0c;目的在于为开发者提供一个易用的软件包分发平台。 链接&#xff1a;https://eur.openeuler.openatom.cn/ 为什么我们需要 EUR 在操作系统的世界&#xff0c;软件包是一等…

数据库基本功之复杂查询-多表连接

1. 简单查询的解析方法 全表扫描:指针从第一条记录开始,依次逐行处理,直到最后一条记录结束;横向选择纵向投影结果集 2. 多表连接 交叉连接(笛卡尔积) 非等值连接 等值连接 内连 外连接(内连的扩展,左外,右外,全连接) 自连接 自然连接(内连,隐含连接条件,自动匹配连接字段) …

以创作之名致敬女性开发者

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 前言 在昨天的2023年3月8日&#xff0c;是咱们女性朋友的节日妇女节&#xff0c;本章将会…