当前位置: 首页 > news >正文

【C++】链表算法习题

在这里插入图片描述
🎆个人主页:夜晚中的人海

在这里插入图片描述

今日语录:不经历风雨,长不成大树,不受百炼,难以成钢。

文章目录

  • ⭐一、两数相加
  • 🏠二、两两交换链表中的节点
  • 🚀三、重排链表
  • 🏖️四、合并K个升序链表
  • 🎄五、K个一组翻转链表

⭐一、两数相加

题目链接:两数相加

题目描述:

在这里插入图片描述

解题思路:
1.由题可知,两个链表都是逆序存储数字,因此它们对应的位置分别就是个位、十位等,直接相加即可

2.相加过程中,我们要注意是否会产生进位,如果产生进位,则再下一次运算时要加上进位(注: 如果在链表的最后一个位置产生进位,我们需要new一个结点用来存储最高位)

代码实现:

class Solution {
public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {ListNode* cur1 = l1,*cur2 = l2;//表示进位int t = 0;//创建头结点ListNode* newnode = new ListNode(0);ListNode* prev = newnode;while(cur1 || cur2 || t){if(cur1){t += cur1->val;cur1 = cur1->next;}if(cur2){t += cur2->val;cur2 = cur2->next;}prev->next = new ListNode(t % 10);prev = prev->next;t /= 10;}prev = newnode->next;delete newnode;return prev;}
};

🏠二、两两交换链表中的节点

题目链接:两两交换链表中的节点

题目描述:

在这里插入图片描述

解题思路:
在这里插入图片描述

代码实现:

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;ListNode* cur = prev->next,*next = cur->next,*nnext = next->next;while(cur && next){//头插链表prev->next = next;next->next = cur;cur->next = nnext;prev = cur;cur = nnext;if(cur)next = cur->next;if(next)nnext = next->next;} prev = newhead->next;delete newhead;return prev;}
};

🚀三、重排链表

题目链接:重排链表

题目描述:

在这里插入图片描述

解题思路:
1.先用快慢指针的方法找出中间节点

2.根据中间节点将链表断开,把中间节点之后的节点进行翻转

3.最后合并两个链表即可

代码实现:

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* cur = slow->next;ListNode* newnode = new ListNode(0);slow->next = nullptr;//翻转链表while(cur){ListNode* next = cur->next;cur->next = newnode->next;newnode->next = cur;cur = next;}//合并两个有序链表ListNode* ret = new ListNode(0);ListNode* prev = ret;ListNode* cur1 = head,*cur2 = newnode->next;while(cur1){//存放第一个链表prev->next = cur1;cur1 = cur1->next;prev = prev->next;//存放第二个链表if(cur2){prev->next = cur2;cur2 = cur2->next;prev = prev->next;}}delete newnode;delete ret;}
};

🏖️四、合并K个升序链表

题目链接:合并K个升序链表

题目描述:

在这里插入图片描述

解题思路:
1.解法一:使用建堆算法。通过建一个小根堆,将所有的头结点都放入堆中,我们就能快速找到最小的那个结点

2.解法二:使用递归算法,将链表划分成两端,分别对左右两个链表进行递归,最终将这两个链表进行合并得到整个有序链表(归并算法的策略)

代码实现:
使用建堆算法:

class Solution {struct cmp{bool operator()(const ListNode* l1,const ListNode* l2){return l1->val > l2->val;}};
public:ListNode* mergeKLists(vector<ListNode*>& lists) {//创建一个小根堆priority_queue<ListNode*,vector<ListNode*>,cmp>heap;for(auto l : lists){if(l)heap.push(l);}//合并K个有序链表ListNode* newnode = new ListNode(0);ListNode* prev = newnode;while(!heap.empty()){ListNode* t = heap.top();heap.pop();prev->next = t;prev = t;if(t->next)heap.push(t->next);}prev = newnode->next;delete newnode;return 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){if(left > right)return nullptr;if(left == right)return lists[left];//划分区间int mid = (left + right) >> 1;ListNode* l1 = merge(lists,left,mid);ListNode* l2 = merge(lists,mid + 1,right);return mergelist(l1,l2);}ListNode* mergelist(ListNode* l1,ListNode* l2){if(l1 == nullptr)return l2;if(l2 == nullptr)return l1;ListNode* newhead = new ListNode(0);ListNode* prev = newhead;ListNode* cur1 = l1,*cur2 = l2;//合并两个有序链表while(cur1 && cur2){if(cur1->val <= cur2->val){prev->next = cur1;prev = cur1;cur1 = cur1->next;}else{prev->next = cur2;prev = cur2;cur2 = cur2->next;}}if(cur1)prev->next = cur1;if(cur2)prev->next = cur2;prev = newhead->next;delete newhead;return prev;}
};

🎄五、K个一组翻转链表

题目链接:K个一组翻转链表

题目描述:

在这里插入图片描述

解题思路:
1.先判断一共要逆序几组,可以使用链表中的总个数 n / k

2.使用两个for循环,外循环表示逆序的组数,内循环表示几个一组(注:在翻转之前先记录一下当前位置,方便我们后续找尾)

3.最后将不需要翻转的结点接上即可

代码实现:

class Solution {
public:ListNode* reverseKGroup(ListNode* head, int k) {//分组int n = 0;ListNode* cur = head;while(cur){cur = cur->next;n++;}n /= k;ListNode* newnode = new ListNode(0);newnode->next = head;cur = head;ListNode* prev = newnode;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;prev = newnode->next;delete newnode;return prev;}
};

今天的分享就到这里啦,希望对您有所帮助,感谢您的阅读!

http://www.dtcms.com/a/596366.html

相关文章:

  • 搭建智能问答系统需要什么文档解析工具?
  • 【C++】(以及大多数编程语言)中常见的 六种基本位运算操作
  • (129页PPT)罗兰贝格银行风险预警管理体系规划(附下载方式)
  • 建设银行网站可以更改个人电话网址大全域名解析
  • 增删查改(其一) —— insert插入 与 select条件查询
  • JuiceSSH+cpolar解锁手机远程Linux新姿势,无需公网IP,固定地址稳定用
  • 传统生产制造企业手写单据数字化落地:旗讯 OCR 的技术实现与系统对接方案
  • 如何添加网站白名单广州建设网站的公司
  • nnUNet 训练与推理命令操作记录
  • 【C#】从一次异步锁逐渐展开浅谈服务器架构解决重复编码问题,我与AI的一次深度讨论得出的一些解决方案
  • PKHeX 宝可梦存档编辑工具 用户可自由修改宝可梦属性、技能、道具、图鉴完成度等信息
  • 深度解析:环形链表——手撕面试经典题
  • elasticsearch集群访问中的通信问题
  • 西安模板网站建设套餐佛山做网站费用
  • 什么是RKNN?
  • 《智元启示录》升级说明:从「AI 思考集」到「AI 决策内参」
  • Ansible 基础配置与负载均衡部署实践
  • 融合先验文本与解剖学知识的多模态回归网络用于舌鳞状细胞癌浸润深度的自动预测|文献速递-文献分享
  • 【负载均衡】LVS DR模式详解
  • 从零搭建 ASP.NET 单文件 Web 项目:一个能真用的 BookShop 管理页实战
  • 安徽专业网站建设长春能开发网站的公司
  • hadoop-3.4.1 单机伪部署
  • Nginx(4)--Nginx与tomcat反向代理和负载均衡
  • 37负载均衡介绍和nginx模块编译安装
  • 网站开发成本都有哪几项北京app建设 网站开发公司
  • 01-总结
  • VR党建赛车模拟系统:让党史学习“开“出沉浸式新体验
  • Logstash 从 MySQL 同步数据到 Kafka
  • 通过 HelloWorld 深入剖析 JVM 启动过程
  • css-文字背景渐变色