复习Day11:链表part04: 206. 反转链表、92. 反转链表II、25. K 个一组翻转链表、148. 排序链表

2023-10-07 00:52

本文主要是介绍复习Day11:链表part04: 206. 反转链表、92. 反转链表II、25. K 个一组翻转链表、148. 排序链表,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

我用的方法是在leetcode再过一遍例题,明显会的就复制粘贴,之前没写出来就重写,然后从拓展题目中找题目来写。辅以Labuladong的文章看。然后刷题不用CLion了,使用leetcode自带的IDE模拟面试环境。

哈希表章节的题目思路很清晰,主要是C++中的写法。

206. 反转链表

如何使用递归解法反转整个 单链表:

class Solution {
public:ListNode* reverseList(ListNode* head) {/* 递归解法 */return reverse(head);}ListNode* reverse(ListNode *head){if(head == nullptr || head->next == nullptr){return head;}ListNode* last = reverse(head->next);head->next->next = head;head->next = nullptr;return last;}
};

reverse 函数定义是这样的:

输入一个节点 head,将「以 head 为起点」的链表反转,并返回反转之后的头结点

原来的链表:

[外链图片转存中…(img-KLgVmb78-1696603051839)]

运行完

ListNode last = reverse(head.next);

[外链图片转存中…(img-J17okqo4-1696603051839)]

链表变成了这样(先不要管递归的压栈的实现细节):

[外链图片转存中…(img-d2chnyBs-1696603051840)]

然后运行

head.next.next = head;

[外链图片转存中…(img-nOEn10VM-1696603051840)]

接下来把head->next指向null,并返回现在的头节点:last

head->next = nullptr;
return last;

[外链图片转存中…(img-dQVs9BKX-1696603051840)]

1、递归函数要有 base case,也就是这句:

if (head == NULL || head->next == NULL) {return head;
}

意思是如果链表为空或者只有一个节点的时候,反转结果就是它自己,直接返回即可。

2、当链表递归反转之后,新的头结点是 last,而之前的 head 变成了最后一个节点,别忘了链表的末尾要指向 null:

head->next = NULL;

92. 反转链表II

leetcode链接:https://leetcode.cn/problems/reverse-linked-list-ii/

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

image

如何反转单链表的一部分?这里迭代解法在之前完全反转链表中已经说过了,这里重点关注递归法

(迭代的思路大概是:先用一个 for 循环找到第 m 个位置,然后再用一个 for 循环将 mn 之间的元素反转)

25. K 个一组翻转链表

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

[外链图片转存中…(img-0ZYveRdG-1696603051840)]

此题见:https://labuladong.github.io/algo/di-yi-zhan-da78c/shou-ba-sh-8f30d/ru-he-k-ge-d591d/

class Solution {
public:ListNode* reverseKGroup(ListNode* head, int k) {if (head == nullptr) return nullptr;// 区间 [a, b) 包含 k 个待反转元素ListNode *a, *b;a = b = head;for (int i = 0; i < k; i++) {// 不足 k 个,不需要反转,base caseif (b == nullptr) return head;b = b->next;}// 反转前 k 个元素ListNode *newHead = reverse(a, b);// 递归反转后续链表并连接起来a->next = reverseKGroup(b, k);return newHead;}ListNode* reverse(ListNode* a, ListNode* b) {ListNode *pre, *cur, *nxt;pre = nullptr; cur = a; nxt = a;// while 终止的条件改一下就行了while (cur != b) {nxt = cur->next;cur->next = pre;pre = cur;cur = nxt;}// 返回反转后的头结点return pre;
}
};

148. 排序链表

class Solution {
public:ListNode* sortList(ListNode* head) {return sortList(head, nullptr);}ListNode* sortList(ListNode* head, ListNode* tail) {if (head == nullptr) {return head;}if (head->next == tail) {head->next = nullptr;return head;}ListNode* slow = head, *fast = head;while (fast != tail) {slow = slow->next;fast = fast->next;if (fast != tail) {fast = fast->next;}}ListNode* mid = slow;return merge(sortList(head, mid), sortList(mid, tail));}ListNode* merge(ListNode* head1, ListNode* head2) {ListNode* dummyHead = new ListNode(0);ListNode* temp = dummyHead, *temp1 = head1, *temp2 = head2;while (temp1 != nullptr && temp2 != nullptr) {if (temp1->val <= temp2->val) {temp->next = temp1;temp1 = temp1->next;} else {temp->next = temp2;temp2 = temp2->next;}temp = temp->next;}if (temp1 != nullptr) {temp->next = temp1;} else if (temp2 != nullptr) {temp->next = temp2;}return dummyHead->next;}
};

这篇关于复习Day11:链表part04: 206. 反转链表、92. 反转链表II、25. K 个一组翻转链表、148. 排序链表的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/155047

相关文章

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

csu1329(双向链表)

题意:给n个盒子,编号为1到n,四个操作:1、将x盒子移到y的左边;2、将x盒子移到y的右边;3、交换x和y盒子的位置;4、将所有的盒子反过来放。 思路分析:用双向链表解决。每个操作的时间复杂度为O(1),用数组来模拟链表,下面的代码是参考刘老师的标程写的。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

hdu 1285(拓扑排序)

题意: 给各个队间的胜负关系,让排名次,名词相同按从小到大排。 解析: 拓扑排序是应用于有向无回路图(Direct Acyclic Graph,简称DAG)上的一种排序方式,对一个有向无回路图进行拓扑排序后,所有的顶点形成一个序列,对所有边(u,v),满足u 在v 的前面。该序列说明了顶点表示的事件或状态发生的整体顺序。比较经典的是在工程活动上,某些工程完成后,另一些工程才能继续,此时

深入手撕链表

链表 分类概念单链表增尾插头插插入 删尾删头删删除 查完整实现带头不带头 双向链表初始化增尾插头插插入 删查完整代码 数组 分类 #mermaid-svg-qKD178fTiiaYeKjl {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

建立升序链表

题目1181:遍历链表 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2744 解决:1186 题目描述: 建立一个升序链表并遍历输出。 输入: 输入的每个案例中第一行包括1个整数:n(1<=n<=1000),接下来的一行包括n个整数。 输出: 可能有多组测试数据,对于每组数据, 将n个整数建立升序链表,之后遍历链表并输出。 样例输

《数据结构(C语言版)第二版》第八章-排序(8.3-交换排序、8.4-选择排序)

8.3 交换排序 8.3.1 冒泡排序 【算法特点】 (1) 稳定排序。 (2) 可用于链式存储结构。 (3) 移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时, 此算法不宜采用。 #include <stdio.h>#include <stdlib.h>#define MAXSIZE 26typedef int KeyType;typedef char In

从0到1,AI我来了- (7)AI应用-ComfyUI-II(进阶)

上篇comfyUI 入门 ,了解了TA是个啥,这篇,我们通过ComfyUI 及其相关Lora 模型,生成一些更惊艳的图片。这篇主要了解这些内容:         1、哪里获取模型?         2、实践如何画一个美女?         3、附录:               1)相关SD(稳定扩散模型的组成部分)               2)模型放置目录(重要)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点