【算法刷题之链表篇(1)】

目录

  • 1.leetcode-82. 删除排序链表中的重复元素 II
    • (1)题目描述
    • (2)方法及思路(一次遍历)
    • (3)代码实现
  • 2.leetcode-19. 删除链表的倒数第 N 个结点
    • (1)题目描述
    • (2)方法一:双指针
    • (3)方法二:计算链表长度(最直观)
    • (4)方法三:栈
  • 3.leetcode-83. 删除排序链表中的重复元素
    • (1)题目描述
    • (2)方法及思路(一次遍历)
    • (3)代码实现
  • 4.leetcode-86. 分隔链表
    • (1)题目描述
    • (2)方法及思路(模拟)
    • (3)代码实现
  • 5.leetcode-25. K 个一组翻转链表(较难)
    • (1)题目描述
    • (2)方法及思路(模拟)
    • (3)代码实现

1.leetcode-82. 删除排序链表中的重复元素 II

(1)题目描述

给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
在这里插入图片描述

(2)方法及思路(一次遍历)

1.我们从指针 prev 指向链表的哑节点,随后开始对链表进行遍历。
2.如果当前 cur与 cur.next对应的元素相同,那么我们就需要将 cur 以及所有后面拥有相同元素值的链表节点全部删除。
3.我们记下这个元素值 ,随后不断将 cur从链表中移除
4.如果cur与cur->next对应的元素不相同,则将prev指向cur所在位置,cur继续往下找。
5.当遍历完整个链表之后,我们返回链表的的哑节点的下一个节点 dummy.next即可。
注意:哑节点可以不用考虑head就被删的特殊情况

(3)代码实现

class Solution {
public:ListNode* deleteDuplicates(ListNode* head) {if(head==NULL){return NULL;}ListNode* newnode=new ListNode(0);ListNode* prev=newnode;prev->next=head;ListNode* cur=head;while(cur!=NULL&&cur->next!=NULL){if(cur->val==cur->next->val){int val=cur->val;while(cur != NULL && cur->val == val){cur = cur->next;}prev->next=cur;}else{prev=cur;cur=cur->next;}}return newnode->next;}
};

2.leetcode-19. 删除链表的倒数第 N 个结点

(1)题目描述

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
在这里插入图片描述

(2)方法一:双指针

思路
1.先定义一个first指针,由于要删掉倒数第n个节点,所以可以让first指针先走n步。
2.当first走完,在定义一个second指针,此时两指针一起走,当first走到尾部时,second就走到了要删掉的节点的前一位。
3.将second所在节点指向它下一位的下一位,即可删掉
注意点:first和second从哪里开始走?first的终止条件是哪里?
first从head出发,终止条件是走到空停止,
而对于second与第一题中一样,引入哑节点,second从此处开始走

代码实现

class Solution {
public:ListNode* removeNthFromEnd(ListNode* head, int n) {ListNode* newnode=new ListNode(0,head);ListNode* cur=head;while(n>0){cur=cur->next;n--;}ListNode* prev=newnode;while(cur){prev=prev->next;cur=cur->next;}prev->next=prev->next->next;return newnode->next;}
};

(3)方法二:计算链表长度(最直观)

思路:
一种容易想到的方法是,我们首先从头节点开始对链表进行一次遍历,得到链表的长度 L。随后我们再从头节点开始对链表进行一次遍历,当遍历到第 L−n+1 个节点时,它就是我们需要删除的节点。
代码实现

class Solution {
public:int getLength(ListNode* head) {int length = 0;while (head) {++length;head = head->next;}return length;}ListNode* removeNthFromEnd(ListNode* head, int n) {ListNode* dummy = new ListNode(0, head);int length = getLength(head);ListNode* cur = dummy;for (int i = 1; i < length - n + 1; ++i) {cur = cur->next;}cur->next = cur->next->next;ListNode* ans = dummy->next;delete dummy;return ans;}
};

(4)方法三:栈

思路:
我们也可以在遍历链表的同时将所有节点依次入栈。根据栈「先进后出」的原则,我们弹出栈的第 n 个节点就是需要删除的节点,并且目前栈顶的节点就是待删除节点的前驱节点。这样一来,删除操作就变得十分方便了。(也就是只要找到就直接操作)
代码实现

class Solution {
public:ListNode* removeNthFromEnd(ListNode* head, int n) {ListNode* dummy = new ListNode(0, head);stack<ListNode*> stk;ListNode* cur = dummy;while (cur) {stk.push(cur);cur = cur->next;}for (int i = 0; i < n; ++i) {stk.pop();}ListNode* prev = stk.top();prev->next = prev->next->next;ListNode* ans = dummy->next;delete dummy;return ans;}
};

3.leetcode-83. 删除排序链表中的重复元素

(1)题目描述

给定一个已排序的链表的头 head ,删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。
在这里插入图片描述

(2)方法及思路(一次遍历)

思路:具体地,我们从指针 cur\textit{cur}cur 指向链表的头节点,随后开始对链表进行遍历。如果当前 cur 与 cur.next 对应的元素相同,那么我们就将 cur.next 从链表中移除;否则说明链表中已经不存在其它与 cur 对应的元素相同的节点,因此可以将 cur 指向 cur.next。

(3)代码实现

class Solution {
public:ListNode* deleteDuplicates(ListNode* head) {if (!head) {return head;}ListNode* cur = head;while (cur->next) {if (cur->val == cur->next->val) {cur->next = cur->next->next;}else {cur = cur->next;}}return head;}
};

4.leetcode-86. 分隔链表

(1)题目描述

给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。
你应当 保留 两个分区中每个节点的初始相对位置。
在这里插入图片描述

(2)方法及思路(模拟)

思路
直观来说我们只需维护两个链表 small 和 large 即可,small 链表按顺序存储所有小于 x 的节点,large 链表按顺序存储所有大于等于 x的节点。遍历完原链表后,我们只要将 small 链表尾节点指向 large 链表的头节点即能完成对链表的分隔。
1.先定义两个哨兵位smallHead和largeHead这样做的目的是为了更方便地处理头节点为空的边界条件。
2.遍历链表,找出小的储存进small,大的储存进large
3.合并链表时注意large节点的指向,并注意要删除largeHead

(3)代码实现

class Solution {
public:ListNode* partition(ListNode* head, int x) {ListNode* small=new ListNode(0);ListNode* smallHead=small;ListNode* large=new ListNode(0);ListNode* largeHead=large;while(head!=NULL){if(head->val<x){small->next=head;small=small->next;}else{large->next=head;large=large->next;}head=head->next;}large->next=NULL;small->next=largeHead->next;delete largeHead;return smallHead->next;}
};

5.leetcode-25. K 个一组翻转链表(较难)

(1)题目描述

给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
在这里插入图片描述

(2)方法及思路(模拟)

思路
1.首先按照k来进行分组,每k个会重新是一个head。
2.然后对每k个数进行反转链表。
3.反转完链表,要注意头和尾与前后的相连,所以在实现反转链表的函数中还要返回头和尾
4.遍历到最后时,如果个数少于k就直接返回
在这里插入图片描述

(3)代码实现

首先先实现部分链表反转部分

    pair<ListNode*,ListNode*> myReserve(ListNode* head,ListNode* tail){ListNode* prev=tail->next;ListNode* p=head;while(prev!=tail){ListNode* nex=p->next;p->next=prev;prev=p;p=nex;}return {tail,head};}

总体部分实现
1.在每次实现完注意要有个prev在head前,一开始就是哨兵位,prev用来与反转完的部分进行连接。prev更新的位置即使在tail处(新head前)
2.还要定义一个next在反转链表之前,也就是在找到新tail时定义在他的后面,用于反转部分尾部的连接

ListNode* reverseKGroup(ListNode* head, int k) {ListNode* hair=new ListNode(0);hair->next=head;ListNode* pre=hair;while(head){ListNode* tail=pre;for (int i = 0; i < k; ++i) {tail = tail->next;if (!tail) {return hair->next;}}ListNode* next=tail->next;pair<ListNode*,ListNode*> result=myReserve(head,tail);head=result.first;tail=result.second; pre->next=head;tail->next=next;pre=tail;head=tail->next;}return hair->next;}

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

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

相关文章

【问题】java序列化,什么时候使用

文章目录 是什么为什么如何做流操作 注事事项 是什么 把对象转换为字节序列的过程称为对象的序列化。 把字节序列恢复为对象的过程称为对象的反序列化。 对象的序列化主要有两种用途&#xff1a;   1&#xff09;把对象的字节序列永久地保存到硬盘上&#xff0c;通常存放在一…

二刷LeetCode--46. 全排列(C++版本),回溯

思路&#xff1a;本题是典型的回溯问题&#xff0c;需要列举出每个排列&#xff0c;因此使用回溯法&#xff0c;对每个使用过的元素进行标记&#xff0c;因此需要一个和Nums同样大的标记数组&#xff0c;每个元素被使用之后在递归之前将其标记为已使用&#xff0c;在递归的时候…

JavaScript面试题(四)

87、事件代理 事件代理 也就是 事件委托不是直接给标签添加事件 是给标签的父级添加事件 通过 事件对象 判断触发事件的标签对象是谁 执行不同的函数程序的语法形式委托的优点减少内存消耗 试想一下&#xff0c;若果我们有一个列表&#xff0c;列表之中有大量的列表项&#xf…

无需公网IP——搭建web站点

文章目录 概述使用 Raspberry Pi Imager 安装 Raspberry Pi OS设置 Apache Web 服务器测试 web 站点安装静态样例站点将web站点发布到公网安装 Cpolar内网穿透cpolar进行token认证生成cpolar随机域名网址生成cpolar二级子域名将参数保存到cpolar配置文件中测试修改后配置文件配…

认识容器,走进Docker

文章目录 容器技术简介容器的核心技术容器平台技术容器的支持技术 Docker理念Docker安装配置阿里云镜像加速器 容器技术简介 一切在云端&#xff0c;万物皆容器&#xff0c;说到容器&#xff0c;大家都会想到Docker,Docker现在几乎是容器的代名词&#xff0c;什么是Docker&…

网络通信原理TCP的四次断开连接(第四十九课)

FIN:发端完成发送任务标识。用来释放一个连接。FIN=1表明此报文段的发送端的数据已经发送完毕,并要求释放连接。 SEQ:序号字段。 TCP链接中传输的数据流中每个字节都编上一个序号。序号字段的值指的是本报文段所发送的数据的第一个字节的序号。 序列号为X ACK :确认号 。 …

ViT模型架构和CNN区别

目录 Vision Transformer如何工作 ViT模型架构 ViT工作原理解析 步骤1&#xff1a;将图片转换成patches序列 步骤2&#xff1a;将patches铺平 步骤3&#xff1a;添加Position embedding 步骤4&#xff1a;添加class token 步骤5&#xff1a;输入Transformer Encoder 步…

【Rust】Rust学习 第十五章智能指针

指针 &#xff08;pointer&#xff09;是一个包含内存地址的变量的通用概念。这个地址引用&#xff0c;或 “指向”&#xff08;points at&#xff09;一些其他数据。Rust 中最常见的指针是第四章介绍的 引用&#xff08;reference&#xff09;。引用以 & 符号为标志并借用…

C# Linq源码分析之Take (三)

概要 本文在前两篇Take源码分析的基础上&#xff0c;着重分析Range参数中有倒数的情况&#xff0c;即分析TakeRangeFromEndIterator的源码实现。 源码及分析 TakeRangeFromEndIterator方法用于处理Range中的开始和结束索引存在倒数的情况。该方法位于Take.cs文件中。通过yie…

Lnton羚通算法算力云平台在环境配置时 OpenCV 无法显示图像是什么原因?

问题&#xff1a; cv2.imshow 显示图像时报错&#xff0c;无法显示图像 0%| | 0/1 [00:00<…

构建 NodeJS 影院微服务并使用 docker 部署【01/4】

图片来自谷歌 — 封面由我制作 一、说明 构建一个微服务的电影网站&#xff0c;需要Docker、NodeJS、MongoDB&#xff0c;这样的案例您见过吗&#xff1f;如果对此有兴趣&#xff0c;您就继续往下看吧。 在本系列中&#xff0c;我们将构建一个 NodeJS 微服务&#xff0c;并使用…

派森 #P121. 序列统计

描述 将用户输入的多个数值&#xff08;以输入为空结束&#xff09;存放至列表中&#xff0c;并完成以下统计计算&#xff1a; 1、计算所有数的最大值&#xff0c;最小值&#xff0c;平均值&#xff1b; 2、计算中位数&#xff0c;中位数&#xff1a;在一个有序数列中位于中件…

qt初入门0:结构体中QString用memset导致崩溃分析及QLatin1String简单查看源码

初识Qt,进行开发时遇到一个崩溃问题 简单整理 1&#xff1a;问题描述如下&#xff0c;结构体中QString成员&#xff0c;然后对结构体调用了memset导致问题&#xff1a; 2&#xff1a;问题分析&#xff0c;加断点调试的方式可以明确分析到行数 可以明确看出&#xff0c;初始化…

Windows下问题定位

1、内存相关知识点&#xff1b; 1&#xff09;windows下32位进程&#xff0c;用户态为2G内存&#xff0c;内核态也为2G内存&#xff1b;却别于linux操作系统&#xff1b; 备注&#xff1a;可以通过命令行与管理员权限&#xff0c;启动3G的用户态空间&#xff0c;但是部…

Java 下载压缩zip

Java压缩zip /*** 下载压缩包** param instId 实例id* param response 响应* author 梁伟浩* date 2023-08-21*/GetMapping("/downloadZip")ApiOperation(value "下载压缩包")ApiImplicitParam(name "instId", value "实例id", r…

git权限问题解决方法Access denied fatal: Authentication failed

文章目录 遇到Access denied 的权限问题解决方法1、git的密码修改过&#xff0c;但是本地没更新。2、确定问题&#xff0c;然后增加配置① 查询用户信息②如果名称和email不对&#xff0c;设置名称&#xff1a;③ 检查ssh-add是否链接正常④ 设置不要每次都输入用户名密码 3、配…

6.小程序api分类

事件监听 以on开头&#xff0c;监听某个事件触发&#xff0c;例如&#xff1a;wx.WindowResize事件 同步 以Sync结尾的是同步&#xff0c;可以通过函数返回值直接获取&#xff0c;例如&#xff1a;wx.setStorageSync 异步 需要通过函数接收调用结果&#xff0c;例如&#…

mysql 数据类型

目录 数值类型 整数 tinyint 位类型 BIT(M) 浮点类型 float [(M, D)] [UNSIGNED] DECIMAL(M, D) [UNSIGNED] 二进制类型 字符型 CHAR(SIZE) VARCHAR(SIZE) 日期类型 DATE/DATETIME/TIMESTAMP string 类型 SET & ENUM 在前面的文章中&#xff0c;有时候茶树数…

【校招VIP】CSS校招考点之选择器优先级

考点介绍&#xff1a; 选择器是CSS的基础&#xff0c;也是校招中的高频考点&#xff0c;特别是复合选择器的执行优先级&#xff0c;同时也是实战中样式不生效的跟踪依据。 因为选择器的种类较多&#xff0c;很难直接记忆&#xff0c;可以考虑选择一个相对值&#xff0c;比如id类…

人大进仓数据库ksql命令基础

测试环境信息: 系统为银河麒麟V10 数据库为Kingbase ES V8 数据库安装目录为/opt/Kingbase/ES/V8 ksql命令位于/opt/Kingbase/ES/V8/Server/bin下 使用--help获取帮助 续上图 1.查看数据库列表 ./ksql -U system -l 2.查看数据库版本 ./ksql -V 3.连接指定的数据库tes…