算法专题八: 链表
目录
- 链表
- 1. 链表的常用技巧和操作总结
- 2. 两数相加
- 3. 两两交换链表中的节点
- 4. 重排链表
- 5. 合并K个升序链表
- 6. K个一组翻转链表
链表
1. 链表的常用技巧和操作总结
- 常用技巧
- 画图!!! 更加直观形象, 便于我们理解
- 引入虚拟头节点, 方便我们对链表的操作, 减少我们对边界情况的考虑. 如果没有虚拟头节点我们可能还需要考虑头插时候的情况进行特殊处理
3. 不要吝啬空间, 大胆定义变量
4. 快慢双指针, (判环, 找链表中环的入口, 找链表中倒数第n个节点)
- 链表中的常用操作
- 创建一个新的节点 使用new
- 尾插的方法
- 头插的方法 (逆序链表)
2. 两数相加
算法原理:
模拟两数相加的过程即可, 使用头插, 取l1的数, l2的数, 累加到t中.
编写代码:
/*** 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;ListNode* prev = newhead;ListNode* cur1 = l1, *cur2 = l2;int t = 0;while(cur1 || cur2 || t){if(cur1){t += cur1->val;cur1 = cur1->next;}if(cur2){t += cur2->val;cur2 = cur2->next;}ListNode* add = new ListNode(t % 10);prev = prev->next = add;t /= 10;}prev = newhead->next;delete newhead;return prev;}
};
3. 两两交换链表中的节点
算法思路: 方法一是使用递归的方法, 方法二就是使用模拟
不要吝啬指针的定义只要我们定义好了上述指针就会发现仅需遍历一遍链表即可讲链表进行交换, 先进行交换, 这里需要修改到三个指针, 如果为偶数的情况下cur和next都不为空, 如果为奇数的情况下next为空, 但是为奇数的情况下我们就不需要进行交换了.
编写代码:
/*** 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;ListNode* prev = newhead, *cur = head, *next = head->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;}cur = newhead->next;delete newhead;return cur;}
};
4. 重排链表
算法思路:
这里把slow后面的部分逆序有两种策略, 第一种包括slow位置, 第二种slow->next的位置进行逆序, 如果按照第二种可以直接slow->next = nullptr讲链表置为空, 如果第一种想要将链表置空需要遍历的时候记录一下位置, 这里我们采用第二种方式只把slow->next的后面置空, 逆序使用双指针法, 合并链表使用头插法, 当然其他方法也可以
/*** 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* fast = head, *slow = head;while(fast && fast->next){fast = fast->next->next;slow = slow->next;}ListNode* cur = slow->next;slow->next = nullptr; ListNode* prev = nullptr;while(cur){ListNode* next = cur->next;cur->next = prev;prev = cur;cur = next;}ListNode* l1 = head;ListNode* l2 = prev;ListNode* newhead = new ListNode; prev = newhead;while(l1){prev = prev->next = l1;l1 = l1->next;if(l2){prev = prev->next = l2;l2 = l2->next;}}delete newhead;}
};
/*** 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* fast = head, *slow = head;while(fast && fast->next){fast = fast->next->next;slow = slow->next;}//头插法进行逆置slow->next后面的部分ListNode* head2 = new ListNode;ListNode* cur = slow->next;slow->next = nullptr;//断开链表while(cur){ListNode* next = cur->next;cur->next = head2->next;head2->next = cur;cur = next;}//合并两个链表尾插ListNode* cur1 = head, *cur2 = head2->next;ListNode* ret = new ListNode;ListNode* prev = ret;while(cur1){prev->next = cur1;prev = prev->next; cur1 = cur1->next;if(cur2){prev->next = cur2;prev = prev->next;cur2 = cur2->next;}}delete ret;delete head2;return; }
};
5. 合并K个升序链表
算法思路:
暴力解法时间复杂度太高了, 而且比较麻烦
- 模拟, 使用堆这个数据结构, 重载比较函数, 先将所有的头节点插入到堆中, 然后取堆顶元素进行合并, 合并之后如果下一个元素存在把下一个元素插入到堆中, 如果堆为空则合并完毕, 注意这里的const修饰的是指针本身, 而不是修饰这个变量, 因为这个变量不是const类型变量, const位置放置错误会导致报错, 注意类型匹配.
/*** 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:class com{public:bool operator()(ListNode* const &l1, ListNode* const &l2){return l1->val > l2->val;}};ListNode* mergeKLists(vector<ListNode*>& lists) {priority_queue<ListNode*, vector<ListNode*>,com> heap;for(auto x : lists)if(x) heap.push(x);ListNode* newhead =new ListNode;ListNode* prev = newhead;while(!heap.empty()){ListNode* t = heap.top();prev = prev->next = t;heap.pop();if(t->next) heap.push(t->next);}prev = newhead->next;delete newhead;return prev;}
};
- 递归
/*** 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* mergeKLists(vector<ListNode*>& lists) {return mergeSort(lists,0,lists.size()-1);}ListNode* mergeSort(vector<ListNode*>& lists,int left,int right){//处理边界if(left > right) return nullptr;if(left == right) return lists[left];//划分区间int mid = (right + left) >> 1;ListNode* l1 = mergeSort(lists, left, mid);ListNode* l2 = mergeSort(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;ListNode* prev = newhead;while(l1 && l2){if(l1->val < l2->val){prev = prev->next = l1;l1 = l1->next;}else{prev = prev->next = l2;l2 = l2->next;}}if(l1) prev->next = l1;if(l2) prev->next = l2;prev = newhead->next;delete newhead;return prev;}
};
6. 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) {ListNode* cur = head; int n = 0;while(cur){cur = cur->next;n++;}n /= k;ListNode* newhead = new ListNode;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;}
};
完
相关文章:

算法专题八: 链表
目录 链表1. 链表的常用技巧和操作总结2. 两数相加3. 两两交换链表中的节点4. 重排链表5. 合并K个升序链表6. K个一组翻转链表 链表 1. 链表的常用技巧和操作总结 常用技巧 画图!!! 更加直观形象, 便于我们理解引入虚拟头节点, 方便我们对链表的操作, 减少我们对边界情况的考…...

MySQL中关于NULL值的六大坑!你被坑过吗?
NULL值是我们在开发过程中的老朋友了,但是这个老朋友在MySQL中有很多坑,我通过这篇文章来总结分享一下,欢迎大家在评论区分享你的看法和踩坑经历。 1、NULL不等于NULL 在MySQL中,执行以下SQL会返回NULL 假如t表有以下数据&#…...

学生学习动机测试:激发潜能,引领未来
学习动机、学习兴趣和学习目标制定是影响学生学习成效的三个关键因素。通过对学生学习动机的测试,我们可以深入了解学生的学习状态,进而采取针对性的措施,激发他们的学习潜能,引导他们走向更加光明的未来。本文将从学习动机、学习兴趣和学习目标制定三个方面,详细探讨学生…...

基于SSM党务政务服务热线管理系统的设计
管理员账户功能包括:系统首页,个人中心,用户管理,部门管理,办事信息管理,信息记录管理,系统管理 前台账号功能包括:系统首页,个人中心,部门,信息…...

OSI参考模型详解:初学者指南与实践案例
OSI参考模型详解:初学者指南与实践案例 OSI(Open System Interconnect)参考模型是一个由国际标准化组织(ISO)提出的七层网络分层模型,它为全球所有互联计算机系统提供了一个通用的通信框架,解决…...

S7-200 SMART 与 S7-1200 之间 TCP 通信— S7-200 SMART 作为服务器
TCP 协议通信 TCP 通信为面向连接的通信,需要双方都调用指令以建立连接及交换数据。S7-200 SMART 与 S7-1200 通过 TCP 通信,在 S7-1200 调用 T-block 指令 ( TCON, TDISCON, TSEND, TRCV ) ,在 S7-200 SMART 调用 Open User Communication …...

Java @RequestPart注解:同时实现文件上传与JSON对象传参
RequestPart注解:用于处理multipart/form-data请求的一部分,通常用于文件上传或者处理表单中的字段。 java后端举例: PostMapping("/fileTest")public AjaxResult fileTest(RequestPart("file") MultipartFile file,Req…...

深度学习基础知识-02 数据预处理
深度学习的数据预处理通常包括: 1.数据清洗:去除错误或不完整的数据。 2.归一化:调整数据范围,如将像素值缩放到0-1。 3.数据增强:通过旋转、缩放等方法增加数据多样性。 4.数据划分:将数据分为训练集、验证…...

【CTF刷题9】2024.10.19
[MoeCTF 2021]babyRCE 考点:关键词过滤(绕过方法参考往期博客) 来源:nssctf <?php$rce $_GET[rce]; if (isset($rce)) {if (!preg_match("/cat|more|less|head|tac|tail|nl|od|vi|vim|sort|flag| |\;|[0-9]|\*|\|\%|\&g…...

WPF中的Setter
在 WPF (Windows Presentation Foundation) 中,Setter 是一个定义控件属性值的标记,通常用在 Style 或 Template 中。Setter 用于指定当某些条件满足时,控件的属性应该如何设置。以下是 Setter 的一些关键点: 属性设置:…...

RabbitMQ下载与配置
安装Erlang Erlang 下载地址如下: https://erlang.org/download/otp_versions_tree.html 安装 RabbitMQ RabbitMQ 下载地址如下: https://www.rabbitmq.com/install-windows.html 查看服务,服务已经正常启动 打开Command Prompt 输入rabb…...

【数据结构与算法】力扣 54. 螺旋矩阵
问题描述 给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。 示例 1: 输入: matrix [[1,2,3],[4,5,6],[7,8,9]] 输出: [1,2,3,6,9,8,7,4,5]示例 2: 输入: ma…...

速通不了的人工智能
下面是一个详细且系统的人工智能学习框架,涵盖了从基础理论到实际应用的各个方面。这个框架包括理论学习、编程实践、项目实战和资源推荐。为了帮助你更好地理解和应用,我会提供一些具体的代码示例。 人工智能学习框架 1. 基础理论 1.1 数学基础 线性代数:向量、矩阵、特…...

微信新功能上线,找工作也能“附近”搞定
大家好,我是小悟 你们听说了吗?微信又双叒叕出新功能啦!这次可不是什么微整形、小游戏之类的小打小闹,而是实实在在的大招——查找附近的工作!没错,你没听错,就是那个在你家门口就能找到工作的…...

CANoe与C#联合仿真方案
引言 CANoe作为一款强大的网络仿真工具,能够模拟各种通信协议,尤其是在汽车领域的CAN、LIN、Ethernet等协议。而C#作为一种广泛使用的编程语言,能够为CANoe提供灵活的用户界面和逻辑控制。本文将探讨如何将CANoe与C#结合,实现高效的联合仿真方案。 1. 系统架构 联合仿真…...

公交信息在线查询系统|基于java和小程序的公交信息在线查询系统小程序设计与实现(源码+数据库+文档)
公交信息在线查询系统小程序 目录 基于java和小程序的公交信息在线查询系统小程序设计与实现 一、前言 二、系统功能设计 三、系统实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍:✌️大厂…...

[LeetCode] 1162. 地图分析
题目描述: 你现在手里有一份大小为 n x n 的 网格 grid,上面的每个 单元格 都用 0 和 1 标记好了。其中 0 代表海洋,1 代表陆地。 请你找出一个海洋单元格,这个海洋单元格到离它最近的陆地单元格的距离是最大的,并返…...

CentOS 上安装 MySQL(附卸载教程)
在 CentOS 上安装 MySQL 5.7: 1. 添加 MySQL Yum 存储库 首先,确保你已添加 MySQL Yum 存储库。因为你已经安装了 mysql57-community-release-el7-11.noarch,如果需要重新添加,可以使用以下命令: sudo yum localins…...

如何在Matlab界面中添加日期选择器?
在Matlab界面中添加日期选择器,可以让用户通过图形界面方便地选择日期。Matlab提供了uidatepicker函数,允许用户在App Designer设计的GUI中添加日期选择器组件。以下是如何在Matlab界面中添加日期选择器的详细步骤: 1. 使用App Designer添加…...

保险系统的部分模式01
Wolfgang Keller 著,liwenhua 译 摘要 对于许多保险公司来说,要建立一个能够缩短产品周期,柔性灵活的保险系统可谓是一个挑战。虽然这个系统有着巨大的市场,围绕这些相同的问题开展了许多项目,但是这些项目似乎仍然有…...

用你的手机/电脑运行文生图方案
随着ChatGPT和Stable Diffusion的发布,最近一两年,生成式AI已经火爆全球,已然成为移动互联网后一个重要的“风口”。就图片/视频生成领域来说,Stable Diffusion模型发挥着极其重要的作用。由于Stable Diffusion模型参数量是10亿参…...

L1正则化详解
目录 L1 正则化优缺点:适合使用L1正则化的情况:不适合使用L1正则化的情况:参考 L1 正则化 L1正则化是一种常用的正则化技术,也被称为Lasso正则化(Least Absolute Shrinkage and Selection Operator)。它通…...

C语言在数据库开发中的应用及其代码实践
数据库作为现代软件开发中不可或缺的一部分,其开发和维护工作至关重要。C语言,以其接近硬件的特性和高效率,被广泛应用于数据库系统的核心组件开发中。本文将探讨C语言在数据库开发中的应用,并提供实际的代码示例。 C语言在数据库…...

java maven
参考链接 maven相关配置 maven依赖管理 依赖具有传递性。 maven依赖范围 maven的生命周期 分为三个相互独立的生命周期: 在执行对应生命周期的操作时,需要进行前面的操作。比如,执行打包install的时候,会执行test。...

Java爬虫:获取直播带货数据的实战指南
在当今数字化时代,直播带货已成为电商领域的新热点,通过直播平台展示商品并进行销售,有效促进了产品的曝光和销售量的提升。然而,如何在直播带货过程中进行数据分析和评估效果,成为了摆在商家面前的一个重要问题。本文…...

python 列表、元组、字典易误区
一、删除元素 1、删除列表中的元素 pop del (1)pop(索引) 用于删除指定索引处的元素,并返回被删除的元素的值。默认删除最后一个元素。 eg:list.pop() (2)del 用于删除列表中的指定索引处的元素,或者删除整个列表变量。del操作没有返回值。 eg:del a[1:…...

wireshark或tshark提取tcpdump捕获的数据包(附python脚本自动解析文件后缀)
tcpdump 捕获数据包后,保存的文件通常会被命名为 capture.pcap(或其他你指定的名称),并存储在你运行命令的当前目录中。以下是如何使用 tcpdump 进行流量捕获,并找到和使用捕获文件的详细步骤。 1. 使用 tcpdump 捕获…...

了解EasyNVR及EasyNVS,EasyNVR连接EasyNVS显示授权超时如何解决?什么原因?
我们先来了解NVR批量管理软件/平台EasyNVR,它深耕市场多年,为用户提供多种协议,兼容多种厂商设备,包括但不限于支持海康,大华,宇视,萤石,天地伟业,华为设备。 NVR录像机…...

【AUTOSAR标准文档】服务类型介绍
Introduction to types of services The Basic Software can be subdivided into the following types of services: ① Input/Output (I/O) Standardized access to sensors, actuators and ECU onboard peripherals ② Memory Standardized access to internal/external…...

Axure垂直菜单展开与折叠
亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! 课程主题:Axure垂直菜单展开与折叠 主要内容:垂直菜单单击实现展开/折叠,点击各菜单项显示选中效果 应用场景:后台菜单设…...