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

leetcode-链表篇3

leetcode-61

给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。

示例 1:

输入:head = [1,2,3,4,5], k = 2
输出:[4,5,1,2,3]

示例 2:

输入:head = [0,1,2], k = 4
输出:[2,0,1]

提示:

  • 链表中节点的数目在范围 [0, 500] 内
  • -100 <= Node.val <= 100
  • 0 <= k <= 2 * 109

思路:看图片可以发现,这个题目本质上,是把链表分成两部分,交换前后两部分的顺序

所以重点在于找到分裂点,以及拼接

/*** 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* rotateRight(ListNode* head, int k) {if(!head || !head->next || k == 0) {return head;}auto tmp = head;int count = 0;auto tail = head;while(tmp) {tail = tmp;tmp = tmp->next;++count;}tmp = head;k %= count;if(k == 0) {return head;}k = count - k;while(--k && tmp) {tmp = tmp->next;}auto new_head = tmp->next;tmp->next = nullptr;tail->next = head;return new_head;}   
};

leetcode-206

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:

输入:head = [1,2]
输出:[2,1]

示例 3:

输入:head = []
输出:[]

提示:

  • 链表中节点的数目范围是 [0, 5000]
  • -5000 <= Node.val <= 5000

进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?

思路:递归法比较简单,还是我们的老模板

void circle(ListNode *head) {if(...) {return }        //边界条件auto res = circle(head->next);//other code//return
}

迭代法也是一器破万法。

关于链表反转的题目,都分成两部分,pre和curr

pre就是已经处理好的部分的尾节点, curr就是你要处理的部分的头节点

所以伪代码如下

//关于翻转链表相关的题目
while(xxx) {process(curr);      //实现翻转的逻辑pre = curr;         //当前部分已经处过,所以pre变成currcurr = curr->next;  //curr->next还没处理过,所以curr指向自己的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* reverseList(ListNode* head) {if(!head || !head->next) {return head;}// auto next = reverseList(head->next);// auto tmp = head->next;// head->next = nullptr;// tmp->next = head;// return next;auto pre = head;pre = nullptr;while(head) {auto next = head->next;head->next = nullptr;head->next = pre;pre = head;head = next;}return pre;}
};

leetcode-92

给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

示例 1:

输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]

示例 2:

输入:head = [5], left = 1, right = 1
输出:[5]

提示:

  • 链表中节点数目为 n
  • 1 <= n <= 500
  • -500 <= Node.val <= 500
  • 1 <= left <= right <= n

进阶: 你可以使用一趟扫描完成反转吗?

思路,和上题一样,不过是对翻转的区间有限制了。

加上前缀节点pre,找到要翻转的区间的头尾节点,将之翻转后。拼接回原来的链表

/*** 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* reverseBetween(ListNode* head, int left, int right) {if(!head || !head->next) {return head;}auto tmp = new ListNode(-1);tmp->next = head;auto pre = tmp;int count = left;while(--count) {tmp = tmp->next;}auto curr = tmp->next;for(int i=0; i<right-left; i++) {auto tail = curr->next->next;auto next = curr->next;curr->next = tail;auto new_tail = tmp->next;tmp->next = next;next->next = new_tail;}return pre->next;}
};

leetcode-24

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

示例 1:

输入:head = [1,2,3,4]
输出:[2,1,4,3]

示例 2:

输入:head = []
输出:[]

示例 3:

输入:head = [1]
输出:[1]

提示:

  • 链表中节点的数目在范围 [0, 100] 内
  • 0 <= Node.val <= 100

思路:还记得我们一器破万法的迭代法模板吗,直接套用就可以

/*** 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 || !head->next) {return head;}auto pre = new ListNode(-1);pre->next = head;auto curr = head;auto tmp = pre;while(curr && curr->next) {auto tail = curr->next->next;auto next = curr->next;curr->next = tail;auto new_tail = tmp->next;next->next = new_tail;tmp->next = next;tmp = curr;curr = curr->next;}return pre->next;}
};

leetcode-25

给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。

k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

示例 1:

输入:head = [1,2,3,4,5], k = 2
输出:[2,1,4,3,5]

示例 2:

输入:head = [1,2,3,4,5], k = 3
输出:[3,2,1,4,5]

提示:
  • 链表中的节点数目为 n
  • 1 <= k <= n <= 5000
  • 0 <= Node.val <= 1000

进阶:你可以设计一个只用 O(1) 额外内存空间的算法解决此问题吗?

思路:做了以上几道题目,总结了自己的一器破万法模板之后,发现这个题竟然这么简单

以前被自己视为面试杀手的接雨水,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) {auto tmp = head;int count=0;while(tmp) {++count;tmp = tmp->next;}if(!head || !head->next || k>count || k<=1) {return head;}auto pre = new ListNode(-1);pre->next = head;tmp = pre;auto curr = head;    for(int i=0; i<count/k; i++) {for(int j=1; j<k; j++) {auto tail = curr->next->next;auto next = curr->next;curr->next = tail;auto new_tail = tmp->next;next->next = new_tail;tmp->next = next;}tmp = curr;curr = curr->next;}return pre->next;}
};

相关文章:

  • 会议平台后端优化方案
  • EasyExcel日常使用总结
  • C++模拟实现vector容器【万字模拟✨】
  • LeetCode 53. 最大子数组和
  • [C++] 小游戏 征伐 SLG DNF 0.0.1 版本 zty出品
  • SpringBoot(Java)实现MQTT连接(本地Mosquitto)通讯调试
  • Leetcode 11.乘最多水的容器(字节,快手面试题)
  • 【Spring基础3】- Spring的入门程序
  • 【python进阶攻略13】协程、内存copy、多进程
  • AI大模型面试大纲
  • Flutter中使用FFI的方式链接C/C++的so库(harmonyos)
  • 万象奥科工业平板上线,邀您体验与众不同!
  • 聊一下数据脱敏
  • 【机器学习(五)】分类和回归任务-AdaBoost算法
  • webpack 4 的 30 个步骤构建 react 开发环境
  • [PHP内核探索]PHP中的哈希表
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 【EOS】Cleos基础
  • 【mysql】环境安装、服务启动、密码设置
  • 03Go 类型总结
  • Angular数据绑定机制
  • CODING 缺陷管理功能正式开始公测
  • css系列之关于字体的事
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • github从入门到放弃(1)
  • HTTP中的ETag在移动客户端的应用
  • Java 多线程编程之:notify 和 wait 用法
  • Javascript Math对象和Date对象常用方法详解
  • js ES6 求数组的交集,并集,还有差集
  • k8s 面向应用开发者的基础命令
  • Objective-C 中关联引用的概念
  • Redis学习笔记 - pipline(流水线、管道)
  • sublime配置文件
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • vue 个人积累(使用工具,组件)
  • Windows Containers 大冒险: 容器网络
  • 搭建gitbook 和 访问权限认证
  • 翻译--Thinking in React
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 时间复杂度与空间复杂度分析
  • 用 vue 组件自定义 v-model, 实现一个 Tab 组件。
  • 国内开源镜像站点
  • ​​​​​​​STM32通过SPI硬件读写W25Q64
  • ​3ds Max插件CG MAGIC图形板块为您提升线条效率!
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • #Datawhale AI夏令营第4期#AIGC方向 文生图 Task2
  • #window11设置系统变量#
  • $GOPATH/go.mod exists but should not goland
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (13):Silverlight 2 数据与通信之WebRequest
  • (Java)【深基9.例1】选举学生会
  • (创新)基于VMD-CNN-BiLSTM的电力负荷预测—代码+数据
  • (附源码)springboot 房产中介系统 毕业设计 312341
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354