算法专题八: 链表
目录
- 链表
- 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 译 摘要 对于许多保险公司来说,要建立一个能够缩短产品周期,柔性灵活的保险系统可谓是一个挑战。虽然这个系统有着巨大的市场,围绕这些相同的问题开展了许多项目,但是这些项目似乎仍然有…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
深入理解Optional:处理空指针异常
1. 使用Optional处理可能为空的集合 在Java开发中,集合判空是一个常见但容易出错的场景。传统方式虽然可行,但存在一些潜在问题: // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统
Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...