力扣 - 92. 反转链表II
题目
思路1(迭代)
- 将反转链表分成3个部分:前一段未反转的部分、待反转链表部分、后一段未反转部分
- 将3个片段分离后,然后再连接起来
- 细节注意:如果是从第一个开始反转链表,即前一段未反转的部分不存在,那么返回的结果就直接是反转链表片段的新节点,否则就是head
代码
class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
if (head == null) {
return null;
}
// cur用于记录当前节点的指向,刚开始就是指向head
ListNode cur = head;
// prev用于记录 前一段未反转的部分 的最后一个节点,默认初始指向null
ListNode prev = null;
// 反转链表后的头结点
ListNode tail = null;
// 用于记录表反转之后的最后一个节点
ListNode reverseTail = null;
// 先获取prev,遍历结束后cur指向的是 待反转链表部分 的起使位置
for (int i = 1; i < m; i++) {
prev = cur;
cur = cur.next;
}
// 待反转链表部分 的起使位置也就是链表反转之后的最后一个节点,我们先记录下来,为了最后和 后一段未反转部分 连接起来
reverseTail = cur;
// 开始反转链表,遍历次数要是n-m+1,这样才能反转全,那么此时cur指向的就是 后一段未反转部分 的起始位置
for (int i = 0; i < n-m+1; i++) {
ListNode next = cur.next;
cur.next = tail;
tail = cur;
cur = next;
}
// 现在将 待反转链表部分 的尾节点与 后一段未反转部分 的起始节点连接起来
reverseTail.next = cur;
// 判断 前一段未反转的部分 的最后一个节点是否为空,如果为空的话,说明反转的是该链表前n个节点,直接返回 反转链后的头结点
if (prev == null) {
return tail;
} else {
// 否则的话,将 前一段未反转的部分 的最后一个节点与 待反转链表部分 的头节点连接起来,然后返回head
prev.next = tail;
return head;
}
}
}
复杂度分析
- 时间复杂度:\(O(N)\)
- 空间复杂度:\(O(1)\)
思路2(递归)
- 我们可以递归实现反转链表
- 然后难度再加深一点,实现反转前 n 个链表
- 但是题目需求是还有前 m-1 个链表节点不需要反转,所以我们通过递归把前 m-1 个个省略跳过即可(递归时候m和n都要同时减1,这样才能保证反转的部分保持不变),当 m 减少为1时,反转前n个即可
- 在 reverseN 中,我们需要一个tail来记录后一部分不反转链表的第一个节点,也是反转链表最后一个节点指向的地方:
head.next = tail;
代码
class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
// m为1代表就是直接反转前n个节点
if (m == 1) {
return reverseN(head, n);
}
head.next = reverseBetween(head.next, m-1, n-1);
return head;
}
/**
* 用于记录反转链表部分的尾结点指向
*/
ListNode tail = null;
/**
* 反转链表的前n个节点
*/
public ListNode reverseN(ListNode head, int n) {
if (n == 1) {
tail = head.next;
return head;
}
ListNode p = reverseN(head.next, n-1);
head.next.next = head;
head.next = tail;
return p;
}
}
复杂度分析
- 时间复杂度:\(O(N)\)
- 空间复杂度:\(O(N)\)
力扣 - 92. 反转链表II的更多相关文章
- LeetCode 92. 反转链表 II(Reverse Linked List II)
92. 反转链表 II 92. Reverse Linked List II 题目描述 反转从位置 m 到 n 的链表.请使用一趟扫描完成反转. 说明: 1 ≤ m ≤ n ≤ 链表长度. LeetC ...
- Java实现 LeetCode 92 反转链表 II
92. 反转链表 II 反转从位置 m 到 n 的链表.请使用一趟扫描完成反转. 说明: 1 ≤ m ≤ n ≤ 链表长度. 示例: 输入: 1->2->3->4->5-> ...
- 92.反转链表II
题目 给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right .请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 . ...
- leetcode 206. 反转链表 及 92. 反转链表 II
206. 反转链表 问题描述 反转一个单链表. 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1-> ...
- 92. 反转链表 II
反转从位置 m 到 n 的链表.请使用一趟扫描完成反转. 说明: 1 ≤ m ≤ n ≤ 链表长度. 示例: 输入: 1->2->3->4->5->NULL, m ...
- 刷题-力扣-541. 反转字符串 II
541. 反转字符串 II 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/reverse-string-ii 著作权归领扣网络所有. ...
- LeetCode 92 ——反转链表 II
1. 题目 2. 解答 我们需要先找到第 m 个结点及其上一个结点,然后将从 m 到 n 的结点进行反转,最后依次将 m 到 n 反转后的结点和 n 之后的结点放入原链表中即可. 从前往后依次遍历 m ...
- LeetCode 92. 反转链表 II(Reverse Linked List II)
题目描述 反转从位置 m 到 n 的链表.请使用一趟扫描完成反转. 说明: 1 ≤ m ≤ n ≤ 链表长度. 示例: 输入: 1->2->3->4->5->NULL, ...
- [LeetCode题解]92. 反转链表 II | 一次遍历 + 反转
解题思路 将链表分为三部分:[0, m).[m, n].(n, L],其中 L 为链表长度. 第一步:使用虚拟头节点 dummy,用于将 head 也能参与操作: 第二步:找到第 m-1 节点(fir ...
随机推荐
- React Hooks: useLayoutEffect All In One
React Hooks: useLayoutEffect All In One useLayoutEffect https://reactjs.org/docs/hooks-reference.htm ...
- Webpack 4.x 默认支持 ES6 语法
Webpack 4.x 默认支持 ES6 语法 Q: 为什么 webpack4 默认支持 ES6 语法的压缩? A: terser 里面实现了 ES6 语法的 AST解析. webpack 4 里使用 ...
- 封装 React Native 原生组件(iOS / Android)
封装 React Native 原生组件(iOS / Android) 在 React Native中,有很多种丰富的组件了,例如 ScrollView.FlatList.SectionList.Bu ...
- eui & search select
eui & search select https://element.eleme.io/#/zh-CN/component/select demo <template> < ...
- vue $emit bug
vue $emit bug https://www.cnblogs.com/xgqfrms/p/11146189.html solution https://forum.vuejs.org/t/emi ...
- 在线预览word,excel,ppt
https://view.officeapps.live.com/op/view.aspx?src=服务器地址微软提供的地址拼接自己的可以预览了拼接自己的服务器地址可以在线预览
- 在.NET Core 中使用 FluentValidation 进行规则验证
不用说,规则验证很重要,无效的参数,可能会导致程序的异常. 如果使用Web API或MVC页面,那么可能习惯了自带的规则验证,我们的控制器很干净: public class User { [Requi ...
- ROS 安装完成后运行小乌龟示例程序
安装ROS成功后,在Beginner Tutorials中有一个简单的示例程序. 在Terminal中运行以下命令: $ roscore 新开一个terminal,运行以下命令,打开小乌龟窗口: $ ...
- Java自学第8期——多线程
1.多线程: 操作系统支持同时运行多个任务,一个任务通常是一个程序,所有运行中的程序就是一个进程().程序内部包含多个顺序执行流,每个顺序执行流就是一个线程. 并发:两个或者多个事件在同一个时间段内交 ...
- Redis 日志篇:系统高可用的杀手锏
特立独行是对的,融入圈子也是对的,重点是要想清楚自己向往怎样的生活,为此愿意付出怎样的代价. 我们通常将 Redis 作为缓存使用,提高读取响应性能,一旦 Redis 宕机,内存中的数据全部丢失,假如 ...