C++ 链表OJ

目录

1、2. 两数相加

2、24. 两两交换链表中的节点

3、143. 重排链表

4、23. 合并 K 个升序链表

5、25. K 个一组翻转链表


解决链表题目常用方法:

1、画图
2、引入虚拟"头”结点

  • 便于处理边界情况
  • 方便我们对链表操作

3、大胆定义变量,减少连接节点时出现错误。

4、快慢双指针

  • 判环
  • 找链表中环的入口
  • 找链表中倒数第 n个结点

1、2. 两数相加

 思路:模拟相加,注意进位问题。

/*** 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* addTwoNumbers(ListNode* l1, ListNode* l2) {ListNode* newhead=new ListNode(0);ListNode* cur1=l1,*cur2=l2;ListNode* cur=newhead;int c=0;//进位while(cur1||cur2||c){if(cur1){c+=cur1->val;cur1=cur1->next;}if(cur2){c+=cur2->val;cur2=cur2->next;}cur->next=new ListNode(c%10);cur=cur->next;c/=10;}cur=newhead->next;delete newhead;return cur;}
};

2、24. 两两交换链表中的节点

 思路:循环、迭代(模拟)。定义一个带有虚拟头结点的链表统计结果,接着定义出包括虚拟头结点在内和它后三个节点方便直接插入新链表。

/*** 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) {if (head == nullptr || head->next == nullptr) {return head;}ListNode* newHead = new ListNode(0);newHead->next = head;ListNode *prev = newHead, *cur = prev->next, *next = cur->next,*nnext = next->next;while (cur && next) {prev->next = next;next->next = cur;cur->next = nnext;prev = cur;cur = prev->next;if (cur)next = cur->next;if (next)nnext = next->next;}cur = newHead->next;delete newHead;return cur;}
};
  • 首先创建一个新的头节点newHead,其值为0,并将其指向原链表的头节点head
  • 使用指针prev指向newHead,指针cur指向prev的下一个节点(即原链表的头节点),指针next指向cur的下一个节点,指针nnext指向next的下一个节点。
  • 进入循环,条件是curnext都不为空。在循环中:
    • prevnext指针指向next,实现交换相邻节点。
    • nextnext指针指向cur,完成节点交换。
    • curnext指针指向nnext,恢复链表连接。
    • 更新prevcurcurprev的下一个节点,nextcur的下一个节点,nnextnext的下一个节点。
  • 循环结束后,重新定位cur指向新链表的头部,即newHead的下一个节点。
  • 删除创建的头节点newHead,并返回交换后链表的头节点cur

3、143. 重排链表

 思路:快慢双指针找到中间节点,逆序后半部分,利用双指针合并两个链表。

/*** 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:void reorderList(ListNode* head) {if (head == nullptr || head->next == nullptr ||head->next->next == nullptr) {return;}ListNode *slow = head, *fast = head;while (fast && fast->next) {slow = slow->next;fast = fast->next->next;}ListNode* rhead = new ListNode(0);ListNode* cur = slow->next;//逆序不要中间节点slow->next = nullptr;//分离逆序部分while (cur) {ListNode* next = cur->next;cur->next = rhead->next;rhead->next = cur;cur = next;}ListNode *cur1 = head, *cur2 = rhead->next;ListNode* ret = new ListNode(0);ListNode* prev = ret;while (cur1) {prev->next = cur1;cur1 = cur1->next;prev = prev->next;if (cur2) {prev->next = cur2;cur2 = cur2->next;prev = prev->next;}}delete rhead;delete ret;}
};

4、23. 合并 K 个升序链表

 思路:把所有的头结点放进⼀个⼩根堆(使用优先级队列实现)中,这样就能快速的找到每次 K 个链表中最⼩的元素是哪个。

/*** 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()(const ListNode* a, const ListNode* b) {return a->val > b->val;}};ListNode* mergeKLists(vector<ListNode*>& lists) {priority_queue<ListNode*, vector<ListNode*>, cmp> heap;for (auto l : lists) {if (l)heap.push(l);}ListNode* ret = new ListNode(0);ListNode* prev = ret;while (!heap.empty()) {ListNode* t = heap.top();heap.pop();prev->next = t;prev = t;if (t->next)heap.push(t->next);}prev = ret->next;delete ret;return prev;}
};
  1. 定义一个比较结构体cmp,用于比较两个节点的值大小,确保优先级队列是一个最小堆。
  2. 遍历输入的链表数组lists,将每个链表的头节点(如果不为空)加入到优先级队列heap中。
  3. 创建一个哑节点ret,它将作为返回的链表的头节点的前驱,用于简化链表操作。同时,使用一个指针prev来跟踪当前链表的最后一个节点。
  4. heap不为空时,循环执行以下操作:
    • heap中取出最小值节点t(即优先级队列的顶部元素),这是当前所有链表头节点中值最小的节点。
    • prevnext指向t,将t接入到当前构建的链表中。
    • 更新prev指向t,即将prev移动到链表的最末端。
    • 如果t还有下一个节点(t->next不为空),则将这个下一个节点加入到heap中,以便继续参与后续的比较和选择过程。
  5. 循环结束后,所有输入的链表已经完全合并到了由ret->next开始的链表中。
  6. 在返回结果之前,首先保存ret->next到一个临时变量prev(这里重新使用prev变量来简化代码,其实是返回链表的头节点),然后删除哑节点ret
  7. 返回prev,即合并后的链表的头节点。

思路二:递归/分治 

class Solution {
public:ListNode* mergeKLists(vector<ListNode*>& lists) {return merge(lists, 0, lists.size() - 1);}ListNode* merge(vector<ListNode*>& lists, int left, int right) {int mid = left + right >> 1;if (left > right)return nullptr;if (left == right)return lists[left]; // 只有一个链表ListNode* l1 = merge(lists, left, mid);ListNode* l2 = merge(lists, mid + 1, right);return mergeTwoList(l1, l2);}ListNode* mergeTwoList(ListNode* l1, ListNode* l2) {if (l1 == nullptr)return l2;if (l2 == nullptr)return l1;ListNode head;ListNode *cur1 = l1, *cur2 = l2, *prev = &head;head.next = nullptr;while (cur1 && cur2) {if (cur1->val <= cur2->val) {prev = prev->next = cur1;cur1 = cur1->next;} else {prev = prev->next = cur2;cur2 = cur2->next;}}if (cur1)prev->next = cur1;if (cur2)prev->next = cur2;return head.next;}
};

5、25. K 个一组翻转链表

 思路:先求出需要逆序的组数n,重复n次长度为k的链表逆序,通过头插到新链表实现逆序,每头插k个元素后更新头插位置。

/*** 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) {int n = 0;ListNode* cur = head;while (cur) {cur = cur->next;n++;}n /= k;ListNode* newhead = new ListNode(0);ListNode* prev = newhead;cur = head;for (int i = 0; i < n; i++) {ListNode* tmp = cur;for (int j = 0; j < k; j++) {ListNode* next = cur->next;cur->next = prev->next;prev->next = cur;cur = next;}prev = tmp;}prev->next = cur;cur = newhead->next;delete newhead;return cur;}
};

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

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

相关文章

STM32CubeMX软件界面花屏,混乱的解决方案。

添加系统环境变量:J2D_D3D 值:false 即可解决。

MySQL:一行记录如何

1、表空间文件结构 表空间由段「segment」、区「extent」、页「page」、行「row」组成&#xff0c;InnoDB存储引擎的逻辑存储结构大致如下图&#xff1a; 行 数据库表中的记录都是按「行」进行存放的&#xff0c;每行记录根据不同的行格式&#xff0c;有不同的存储结构。 页…

机器学习中类别不平衡问题的解决方案

类别不平衡问题 解决方案简单方法收集数据调整权重阈值移动 数据层面欠采样过采样采样方法的优劣 算法层面代价敏感集成学习&#xff1a;EasyEnsemble 总结 类别不平衡&#xff08;class-imbalance&#xff09;就是指分类任务中不同类别的训练样例数目差别很大的情况 解决方案…

信呼OA普通用户权限getshell方法

0x01 前言 信呼OA是一款开源的OA系统&#xff0c;面向社会免费提供学习研究使用&#xff0c;采用PHP语言编写&#xff0c;搭建简单方便&#xff0c;在中小企业中具有较大的客户使用量。从公开的资产治理平台中匹配到目前互联中有超过1W的客户使用案例。 信呼OA目前最新的版本是…

码住!微信自动回复的实现方式

对于很多企业和个人来说&#xff0c;如何高效地回复微信客户消息是一个非常重要的问题。在这样的需求下&#xff0c;使用微信管理系统的机器人自动回复功能成为了一种不错的选择。 1、自动通过好友 当有大量的好友请求时&#xff0c;手动处理好友申请会变得非常繁琐。而微信管…

C++max函数的使用案例20个

文章目录 1. **基本用法&#xff1a;**2. **比较浮点数&#xff1a;**3. **比较字符串&#xff1a;**4. **使用自定义比较函数&#xff1a;**5. **比较容器中的元素&#xff1a;**6. **使用std::initializer_list&#xff1a;**7. **变长参数版本&#xff08;C11及以上&#xf…

Elasticsearch搜索引擎

目录 初识elasticsearch 了解ES 什么是elasticsearch elasticsearch的发展 搜索引擎技术排名&#xff1a; 总结 倒排索引 正向索引和倒排索引 正向索引 倒排索引 总结 es的一些概念 文档 索引 概念对比 架构 总结 安装es&#xff0c;kibana 安装es 安装kiba…

Redis的三种集群模式(图解)

主从复制模式 一个主节点和多个从节点。主节点提供写入和读取功能&#xff0c;但是从属节点只提供读取功能。 主从复制的数据同步过程如下&#xff1a; &#xff08;1&#xff09;首先主节点启动&#xff0c;然后从属节点启动&#xff0c;从属节点会连接主节点并发送SYNC命令以…

Android多线程实现方式及并发与同步,Android面试题汇总

一. 开发背景 想要成为一名优秀的Android开发&#xff0c;你需要一份完备的知识体系&#xff0c;在这里&#xff0c;让我们一起成长为自己所想的那样。 我们的项目需要开发一款智能硬件。它由 Web 后台发送指令到一款桌面端应用程序&#xff0c;再由桌面程序来控制不同的硬件设…

python 蓝桥杯填空题

文章目录 字母数判断列名&#xff08;进制问题&#xff09;特殊日期大乘积星期几 字母数 由于是填空题&#xff0c;那么寻找的话&#xff0c;就直接让每一个位置都是A,通过计算看看是不是结果大于2022即可 判断列名&#xff08;进制问题&#xff09; 这道题目&#xff0c;我们可…

Claude 3家族惊艳亮相:AI领域掀起新浪潮,GPT-4面临强劲挑战

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法|MySQL| ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-agd7RSCGMblYxo85 {font-family:"trebuchet ms",verdana,arial,sans-serif;f…

chatgpt-3的文章生成器有哪些?可以批量生成文章的生成器

GPT-3&#xff08;Generative Pre-trained Transformer 3&#xff09;作为人工智能领域的一项重大突破&#xff0c;开启了新一代的文本生成技术。同时市面上也涌现出了一些GPT-3文章生成器&#xff0c;为用户提供了快速、高效地生成各种类型文章的工具。本文将介绍一些中国的GP…

[BUG]vscode插件live server无法自动打开浏览器

问题描述&#xff1a; 点了open with live server但是浏览器没有自动跳出来 http://127.0.0.1:5500/里面是有东西的 解决方法&#xff1a; 配置环境变量&#xff0c;在path中添加program files

2023天津公租房网上登记流程图,注册到信息填写

2023年天津市公共租赁住房网上登记流程图 小编为大家整理了天津市公共租赁住房网上登记流程&#xff0c;从登记到填写信息。 想要体验的朋友请看一下。 申请天津公共租赁住房时拒绝申报家庭情况会怎样&#xff1f; 天津市住房保障家庭在享受住房保障期间&#xff0c;如在应申…

闰年导致的哪些 Bug

每次闰年对程序员们都是一个挑战&#xff0c;平时运行好好的系统&#xff0c;在 02-29 这一天&#xff0c;好像就会有各种毛病。 虽然&#xff0c;提前一天&#xff0c;领导们都会提前给下面打招呼。但是&#xff0c;不可避免的&#xff0c;今天公司因为闰年还是有一些小故障。…

BUUCTF-Misc-百里挑一

题目链接&#xff1a;BUUCTF在线评测 (buuoj.cn) 下载附件打开是一个流量包文件&#xff1a; 全是在传图片时候的流量&#xff0c;先把图片保存出来文件–>导出对象–>HTTP–>保存到一个文件夹 然后使用kali下的exiftool找到了一半flag exiftool *|grep flag 另外一半…

vulhub中ThinkPHP5 5.0.23 远程代码执行漏洞复现

ThinkPHP是一款运用极广的PHP开发框架。其5.0.23以前的版本中&#xff0c;获取method的方法中没有正确处理方法名&#xff0c;导致攻击者可以调用Request类任意方法并构造利用链&#xff0c;从而导致远程代码执行漏洞。 环境启动后&#xff0c;访问http://your-ip:8080即可看到…

Linux系统:内核参数调优

目录 1、/proc目录 2、sysctl命令 3.1 控制源路由验证 3.2 控制内核的系统请求调试功能 3.3 控制核心转储是否将PID附加到核心文件名 3.4 控制TCP同步cookie的使用 3.5 在网桥上禁用netfilter 3.6 控制消息队列的默认最大大小 3.7 调试TCP内核参数 3.8 调试套…

(学习日记)2024.03.06:UCOSIII第八节:空闲任务+阻塞延时+main函数修改

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

【高效开发工具系列】vimdiff简介与使用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…