【LeetCode算法系列题解】第21~25题

CONTENTS

    • LeetCode 21. 合并两个有序链表(简单)
    • LeetCode 22. 括号生成(中等)
    • LeetCode 23. 合并K个升序链表(困难)
    • LeetCode 24. 两两交换链表中的节点(中等)
    • LeetCode 25. K 个一组翻转链表(困难)

LeetCode 21. 合并两个有序链表(简单)

【题目描述】

将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

【示例1】

在这里插入图片描述

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

【示例2】

输入:l1 = [], l2 = []
输出:[]

【示例3】

输入:l1 = [], l2 = [0]
输出:[0]

【提示】

两个链表的节点数目范围是 [0, 50]
− 100 ≤ N o d e . v a l ≤ 100 -100\le Node.val\le 100 100Node.val100
l1l2 均按非递减顺序排列

【分析】


直接模拟即可,每次取两个链表中较小的结点,接到新链表的后面,如果其中一个链表空了,则直接将另一个链表接到新链表的后面。


【代码】

/*** 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* mergeTwoLists(ListNode* list1, ListNode* list2) {auto dummy = new ListNode(-1), cur = dummy;  // 用auto才能并排写while (list1 && list2)if (list1->val < list2->val) cur = cur->next = list1, list1 = list1->next;else cur = cur->next = list2, list2 = list2->next;if (list1) cur->next = list1;else if (list2) cur->next = list2;return dummy->next;}
};

LeetCode 22. 括号生成(中等)

【题目描述】

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的括号组合。

【示例1】

输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

【示例2】

输入:n = 1
输出:["()"]

【提示】

1 ≤ n ≤ 8 1\le n\le 8 1n8

【分析】


本题只有小括号,对于这类问题,判断一个括号序列是否合法有一些很重要的推论:

  • 任意前缀中,( 数量一定大于等于 ) 数量(最重要);
  • () 的数量相等。

我们可以使用 DFS 搜索方案,对于每个位置,只要当前 ( 的数量小于 n n n 就可以填入,而填入 ) 需要满足当前 ) 的数量小于 n n n 且小于 ( 的数量。


【代码】

class Solution {
public:vector<string> res;vector<string> generateParenthesis(int n) {dfs(n, 0, 0, "");return res;}void dfs(int n, int lc, int rc, string now)  // lc和rc分别表示左右括号的数量{if (lc == n && rc == n) { res.push_back(now); return; }if (lc < n) dfs(n, lc + 1, rc, now + '(');if (rc < n && rc < lc) dfs(n, lc, rc + 1, now + ')');}
};

LeetCode 23. 合并K个升序链表(困难)

【题目描述】

给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。

【示例1】

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[1->4->5,1->3->4,2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6

【示例2】

输入:lists = []
输出:[]

【示例3】

输入:lists = [[]]
输出:[]

【提示】

k = = l i s t s . l e n g t h k == lists.length k==lists.length
0 ≤ k ≤ 1 0 4 0\le k\le 10^4 0k104
0 ≤ l i s t s [ i ] . l e n g t h ≤ 500 0\le lists[i].length\le 500 0lists[i].length500
− 1 0 4 ≤ l i s t s [ i ] [ j ] ≤ 1 0 4 -10^4\le lists[i][j]\le 10^4 104lists[i][j]104
lists[i]升序排列
lists[i].length 的总和不超过 1 0 4 10^4 104

【分析】


和第21题差不多,我们每次从这 K K K 个链表中找出最小的结点,将其接到新链表的后面,可以使用一个小根堆(优先队列 priority_queue 来维护最小值)。需要注意的是我们需要写一个排序算法,C++ 中优先队列的排序算法不是传入一个函数,而是重载了 () 的结构体,具体实现方式见代码部分。


【代码】

/*** 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:struct Cmp{// 默认是大根堆,因此用大于号翻转为小根堆,注意一定要有{}bool operator() (ListNode*& a, ListNode*& b) { return a->val > b->val; } };ListNode* mergeKLists(vector<ListNode*>& lists) {auto dummy = new ListNode(-1), cur = dummy;priority_queue<ListNode*, vector<ListNode*>, Cmp> Q;  // 传入比较结构体for (auto list: lists)if (list) Q.push(list);  // 判断是否为空while (Q.size()){auto t = Q.top(); Q.pop();cur = cur->next = t;if (t->next) Q.push(t->next);}return dummy->next;}
};

LeetCode 24. 两两交换链表中的节点(中等)

【题目描述】

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

【示例1】

在这里插入图片描述

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

【示例2】

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

【示例3】

输入:head = [1]
输出:[1]

【提示】

链表中节点的数目在范围 [0, 100]
0 ≤ N o d e . v a l ≤ 100 0\le Node.val\le 100 0Node.val100

【分析】


我们通过画图可以更加直观地分析:

在这里插入图片描述

具体步骤如下:

  1. P->nextP->next->next 存在时,将其分别记为 AB
  2. P->next = B
  3. A->next = B->next
  4. B->next = A
  5. P = A

【代码】

/*** 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* swapPairs(ListNode* head) {auto dummy = new ListNode(-1), cur = dummy;dummy->next = head;while (cur->next && cur->next->next){auto a = cur->next, b = cur->next->next;cur->next = b, a->next = b->next, b->next = a, cur = a;}return dummy->next;}
};

LeetCode 25. 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 n n
1 ≤ k ≤ n ≤ 5000 1\le k\le n\le 5000 1kn5000
0 ≤ N o d e . v a l ≤ 1000 0\le Node.val\le 1000 0Node.val1000

【分析】


和上一题的分析类似,我们先画出示意图:

在这里插入图片描述

具体步骤如下:

  1. 先遍历一次看看 P 后面是否存在 K 个结点,若不存在直接返回结果,若存在则记最后一个结点为 V
  2. 分别将 P->nextP->next->next 记为 AB
  3. P->next = V
  4. A->next = V->next
  5. P = A
  6. B->next 记为 C
  7. B->next = A
  8. A = B, B = C
  9. 重复6~8共 K − 1 K-1 K1 次。

【代码】

/*** 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) {auto dummy = new ListNode(-1), cur = dummy;dummy->next = head;while (true){auto v = cur;for (int i = 0; i < k; i++)if (v->next == nullptr) return dummy->next;else v = v->next;auto a = cur->next, b = cur->next->next;cur->next = v, a->next = v->next, cur = a;for (int i = 0; i < k - 1; i++){auto c = b->next;b->next = a, a = b, b = c;}}return dummy->next;  // 此行避免报错,不会执行}
};

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

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

相关文章

【SpringBoot】用SpringBoot代码详细解释<List>的用法

在Spring Boot应用程序中&#xff0c;我们可以使用Java集合框架中的List接口来存储并操作一组数据。 List是Java集合框架中的一种数据结构&#xff0c;用于存储一组有序的元素。使用List可以方便地向其中添加、删除或者修改元素&#xff0c;也可以通过下标或者迭代器遍历其中的…

YOLO数据集划分(训练集、验证集、测试集)

1.将训练集、验证集、测试集按照7:2:1随机划分 1.项目准备 1.在项目下新建一个py文件&#xff0c;名字就叫做splitDataset1.py 2.将自己需要划分的原数据集就放在项目文件夹下面 以我的为例&#xff0c;我的原数据集名字叫做hatDataXml 里面的JPEGImages装的是图片 Annota…

【提示工程】询问GPT返回Json结构数据

theme: orange 众所周知&#xff0c;我们可以通过构建的Prompt获取期望的内容&#xff0c;但是通常都是以自然语言返回的&#xff0c;假如我们想得到结构化的数据&#xff0c;比如Json&#xff0c;XML那么怎么办&#xff0c;这篇文章给你一个思路。 理所当然的想法 要实现询问大…

python类的属性和实例的属性有什么区别

在 Python 中&#xff0c;类属性和实例属性是两种不同类型的属性&#xff0c;它们在用途和作用域上有所不同。下面是关于它们的区别的详细解释&#xff1a; 定义位置&#xff1a; 类属性&#xff1a;定义在类的主体中&#xff0c;但在任何类方法之外。实例属性&#xff1a;通常…

【深度学习】ChatGPT

本文基于Andrej Karpathy(OpenAI 联合创始人&#xff0c;曾担任特斯拉的人工智能和自动驾驶视觉主管)在Microsoft Build 2023上的演讲整理而成&#xff08;完整的视频在文末&#xff0c;直接拖到文章底部&#xff09;&#xff0c;主要分为2大部分&#xff1a; 1.如何训练GPT(可…

亚马逊的邮箱可以更改吗,修改亚马逊账户邮箱的方法

亚马逊的邮箱可以更改吗&#xff1f; 可以更改&#xff0c;但更改主户邮箱需要电话对身份进行深度验证。如果需要修改&#xff0c;可以先开case向客服说明情况&#xff0c;然后根据客服的指导步骤来操作即可。 修改亚马逊账户邮箱的方法 1、登录您的账户&#xff1a;打开亚马…

如何有效防止服务器被攻击?

随着互联网的快速发展&#xff0c;服务器安全问题日益引起人们的关注。近期&#xff0c;全球范围内频繁发生的服务器攻击事件引发了广泛关注。为了保护企业和个人的数据安全&#xff0c;有效防止服务器被攻击已成为迫在眉睫的任务。 首先&#xff0c;及时更新服务器的操作系统和…

《C和指针》笔记20:布尔值的注意事项

比较布尔值的时候下面的代码看起来是一样的。 #define FALSE 0 #define TRUE 1 if(flag FALSE) if(!f1ag) ... if(flag TRUE) if(flag) ...但是&#xff0c;如果flag设置为任意的整型值&#xff0c;那么第2对语句就不是等价的。只有当flag确实是TRUE或FALSE&#xff0c;或者…

C++|观察者模式

观察者模式&#xff1a; 定义对象间的一种一对多&#xff08;变化&#xff09;的依赖关系&#xff0c;以便当一个 对象(Subject)的状态发生改变时&#xff0c;所有依赖于它的对象都 得到通知并自动更新 动机&#xff1a; 在软件构建过程中&#xff0c;我们需要为某些对象建立…

数学之美 — 1

为什么你会想和他人共享那些美丽的事物呢&#xff1f;因为这会让他&#xff08;她&#xff09;感到愉悦&#xff0c;也能让你在分享的过程中重新欣赏一次事物的美。 ——David Blackwell 1、感官之美&#xff0c;对于那些有规律的事物&#xff0c;你可以利用自己的视觉、触觉、…

Java实战场景下的ElasticSearch

文章目录 前言一、环境准备二、RsetAPI操作索引库1.创建索引库2.判断索引库是否存在3.删除索引库 二、RsetAPI操作文档1.新增文档2.单条查询3.删除文档4.增量修改5.批量导入6.自定义响应解析方法 四、常用的查询方法1.MatchAll():查询所有2.matchQuery():单字段查询3.multiMatc…

【ES6】JavaScript中的异步编程:async和await

在JavaScript中&#xff0c;异步编程是一种处理长时间运行的操作的方法&#xff0c;这些操作包括读取文件、网络请求或处理大数据等。在传统的回调函数中&#xff0c;代码按照顺序执行&#xff0c;一旦遇到长时间运行的操作&#xff0c;就需要回调函数来处理结果。这使得代码变…

python自动化测试- 自动化框架及工具

1 概述 手续的关于测试的方法论&#xff0c;都是建立在之前的文章里面提到的观点&#xff1a; 功能测试不建议做自动化接口测试性价比最高接口测试可以做自动化 后面所谈到的 测试自动化 也将围绕着 接口自动化 来介绍。 本系列选择的测试语言是 python 脚本语言。由于其…

C# NetTopologySuite+ProjNet 任意图形类型坐标转换

添加引用&#xff1a;NetTopologySuite、ProjNet、ProjNet.SRID Program.cs文件&#xff1a; using ProjNet.CoordinateSystems; using ProjNet.CoordinateSystems.Transformations; using ProjNet.SRID; using System; using System.Collections.Generic; using System.Linq;…

python通过docker打包执行

背景 正常情况下,python脚本执行需要安装有python环境,那python环境虽然也可以通过移植的方法来安装,那总归是比较麻烦的,下面通过docker打包的方式来执行python脚本 1、安装python镜像 准备两个文件即可,dockerfile、requirements.txt两个文件的内容分别如下 同目录下…

泼辣修图Ploarr5.11.7电脑最新简体中文版下载

泼辣修图专业版是一款强大的专业修图软件&#xff0c;拥有上百款调色工具还有丰富的图层素材&#xff0c; 更有智能的人像修饰面板&#xff0c;具备物体识别的智能蒙板&#xff0c;高效的滤镜管理系统和强大的文字工具&#xff0c;支持批量处理。一切围绕摄影&#xff0c;无论是…

elasticsearch批量索引数据示例

示例数据文件document.json(index表示在索引中增加或替换现有文档&#xff0c;create表示如果文档不存在则添加文档,delete表示删除文档): { "index": { "_index": "addr", "_type": "contact", "_id": 1 }}{ &q…

更新Android Studio 到 4.1 后无法启动

更新Android Studio 到 4.1 后无法启动 环境问题解决 环境 升级 Android Studio 到 2022.3 问题 觉得C盘占用太高&#xff0c;就选择了安装到D盘&#xff0c;安装完成后&#xff0c;启动就一直停在启动界面&#xff0c;没有响应。 删除重装、重新下载新版本、下载免安装包、…

【ES6】 JavaScript 中的Object.assign

Object.assign() 是 JavaScript 中的一个方法&#xff0c;它用于复制源对象的所有可枚举属性到目标对象。该方法会返回目标对象。 这是其基本用法&#xff1a; let target Object.assign({}, source);在这个例子中&#xff0c;source 对象的所有可枚举属性都被复制到了 targ…

只考一门数据结构!安徽工程大学计算机考研

安徽工程大学 考研难度&#xff08;☆&#xff09; 内容&#xff1a;23考情概况&#xff08;拟录取和复试分析&#xff09;、院校概况、23专业目录、23复试详情、各专业考情分析、各科目考情分析。 正文992字&#xff0c;预计阅读&#xff1a;3分钟 2023考情概况 安徽工程大…