力扣92(java&python)-反转链表Ⅱ(中等)
题目:
给你单链表的头指针 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
进阶: 你可以使用一趟扫描完成反转吗?
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/reverse-linked-list-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
一、头插法
1.首先定义一个虚拟头结点指向原始头结点,可以减少对头结点的特殊处理,将头结点当做普通结点处理;
2.定义两个指针一个为pre,一个为cur;
3.确定pre和cur指针的位置,需要根据题中给定的left值进行确定,将pre移动到第一个需要反转的结点的前面,将cur移动到需要反转的第一个结点上;
4.将cur后面一个结点temp保存,将当前cur指向cur的下下个结点,即cur.next=cur.next.next , 然后将保存的结点插入到pre后面;
5.重复步骤4;
6.最后返回dummyHead.next。
解释:
temp.next = pre.next这里为什么不能写成temp.next = cur?
看上面的图解就可以看出,cur所指向的结点没有变过,但是所在的位置是一直在变化的,pre和cur中间会一直插入结点,而每次插入都是在pre的后面。如果写成temp.next = cur就会删除上面已经反转的结点,比如4和3。
java代码:
1 /**
2 * Definition for singly-linked list.
3 * public class ListNode {
4 * int val;
5 * ListNode next;
6 * ListNode() {}
7 * ListNode(int val) { this.val = val; }
8 * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
9 * }
10 */
11 class Solution {
12 public ListNode reverseBetween(ListNode head, int left, int right) {
13 ListNode dummyHead = new ListNode(0,head);
14 //定义两个指针pre和cur
15 ListNode pre = dummyHead;
16 ListNode cur = dummyHead.next;
17
18 //先确定两个指针的初始位置,pre应该在left-1,cur=left
19 for(int i = 1; i < left; i++){
20 pre = pre.next;
21 cur = cur.next;
22 }
23 //插入
24 for(int j = 1; j < right - left + 1; j++){
25 //保存cur的下一个结点
26 ListNode temp = cur.next;
27 //使cur指向它的下下个结点
28 cur.next = cur.next.next;
29 //将保存的结点插入
30 temp.next = pre.next;
31 pre.next = temp;
32 }
33 return dummyHead.next;
34
35 }
36 }
python3代码:
1 # Definition for singly-linked list.
2 # class ListNode:
3 # def __init__(self, val=0, next=None):
4 # self.val = val
5 # self.next = next
6 class Solution:
7 def reverseBetween(self, head: Optional[ListNode], left: int, right: int) -> Optional[ListNode]:
8 dummyHead = ListNode(0,head)
9 pre,cur = dummyHead,dummyHead.next
10
11 # 确定pre和cur的位置
12 for i in range(1,left):
13 cur = cur.next
14 pre = pre.next
15
16 # 插入操作
17 for i in range(1,right-left+1):
18 temp = cur.next
19 # 如果temp是尾结点cur.next为none
20 cur.next = temp.next if temp else None
21
22 temp.next = pre.next
23 pre.next = temp
24
25 return dummyHead.next
二、递归
1 /**
2 * Definition for singly-linked list.
3 * public class ListNode {
4 * int val;
5 * ListNode next;
6 * ListNode() {}
7 * ListNode(int val) { this.val = val; }
8 * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
9 * }
10 */
11 class Solution {
12 public ListNode reverseBetween(ListNode head, int left, int right) {
13 if (left == 1){
14 return reversTopN(head, right);
15 }
16 //翻转
17 ListNode between = reverseBetween(head.next, left-1, right-1);
18 //将翻转后的新头结点挂在原来的head之后
19 head.next = between;
20 //返回链表
21 return head;
22 }
23 //nextnode第n个结点之后的结点
24 ListNode nextnode = null;
25 private ListNode reversTopN(ListNode head, int n){
26 //如果只翻转一个,把下一个结点直接放在头结点后
27 if(n == 1){
28 nextnode = head.next;
29 return head;
30 }
31 ListNode newHead = reversTopN(head.next, n-1);
32 //头结点的下一个结点指向头结点
33 head.next.next = head;
34 head.next = nextnode;
35 return newHead;
36 }
37 }
力扣92(java&python)-反转链表Ⅱ(中等)的更多相关文章
- 力扣(LeetCode)反转链表 个人题解
反转一个单链表. 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 进阶:你可以迭代或 ...
- 力扣 - 92. 反转链表II
目录 题目 思路1(迭代) 代码 复杂度分析 思路2(递归) 代码 复杂度分析 题目 92. 反转链表 II 思路1(迭代) 将反转链表分成3个部分:前一段未反转的部分.待反转链表部分.后一段未反转部 ...
- 力扣—Reorder List(重排链表)python实现
题目描述: 中文: 给定一个单链表 L:L0→L1→…→Ln-1→Ln ,将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→… 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点 ...
- 力扣——Partition List(分隔链表) python实现
题目描述: 中文: 给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前. 你应当保留两个分区中每个节点的初始相对位置. 示例: 输入: head = ...
- 【力扣】82. 删除排序链表中的重复元素 II
存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字. 返回同样按升序排列的结果链表. 示例 1: 输入:hea ...
- 第92题:反转链表II
一. 问题描述 反转从位置 m 到 n 的链表.请使用一趟扫描完成反转. 说明: 1 ≤ m ≤ n ≤ 链表长度. 示例: 输入: 1->2->3->4->5->NUL ...
- LeetCode(92):反转链表 II
Medium! 题目描述: 反转从位置 m 到 n 的链表.请使用一趟扫描完成反转. 说明:1 ≤ m ≤ n ≤ 链表长度. 示例: 输入: 1->2->3->4->5-&g ...
- 力扣题目汇总(反转字符串中的单词,EXCEL表列序号,旋置矩阵)
反转字符串中的单词 III 1.题目描述 给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序. 示例 1: 输入: "Let's take LeetCode ...
- 力扣(LeetCode)环形链表 个人题解
给定一个链表,判断链表中是否有环. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 pos 是 -1,则在该链表中没有环. 示例 1: 输入: ...
- 力扣题解-面试题22. 链表中倒数第K个节点
题目描述 输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点.例如,一个链表有6个节点,从头节点开始,它们的值依次是1.2.3.4.5. ...
随机推荐
- Android 多module情况下module依赖aar问题处理
原文: Android 多module情况下module依赖aar问题处理 - Stars-One的杂货小窝 问题描述 负责一个大项目Android工程项目,新增了一个module,而此module由 ...
- Rust Rocket简单入门
目录 简介 hello world 常用功能 动态路径 多个片段(segments) 静态文件服务器 简单WebAPI示例 添加依赖 实现接口 接口测试 参考链接 简介 Rust中最知名的两个web框 ...
- 记录-使用双token实现无感刷新,前后端详细代码
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前言 近期写的一个项目使用双token实现无感刷新.最后做了一些总结,本文详细介绍了实现流程,前后端详细代码.前端使用了Vue3+Vite ...
- 记录--手写$forceUpdate,vm.$destroy方法
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 vm.$forceUpdate (1)作用 迫使Vue.js实例重新渲染.注意它仅仅影响实例本身以及插入插槽内容的子组件,而不是所有子组件 ...
- 记录--微信小程序获取用户信息的最新方法记录
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 微信小程序获取用户信息的几种方式 以下三种方式都无法获取到用户的openID 1. 开放组件获取用户信息<open-data> ...
- .NET Emit 入门教程:第三部分:构建模块(Module)
前言: 在这一部分中,我们将深入讨论动态程序集中模块的概念以及如何构建和管理模块. 1.模块的概念: 模块是动态程序集中的基本单位,它类似于一个独立的代码单元,可以包含类型.方法.字段等成员. 在动态 ...
- MySQL报语法错误,排查竟然花了一个钟!!!!
背景:最近协助远程同事开发一个功能,我调用同事写的接口,出现报错,影响和前端联调,同事正在处理其他事情,暂时无暇顾及.遂自行解决.查看日志现发一个inser语句报语法错误. 异常日志: bad SQL ...
- 《On Java 8》笔记
第一章 对象的概念 复用 组合和聚合 组合(Composition)经常用来表示"拥有"关系(has-a relationship).例如,"汽车拥有引擎" 聚 ...
- Oracle字符串分隔函数
记录一下 CREATE OR REPLACE TYPE str_split IS TABLE OF VARCHAR2 (4000); CREATE OR REPLACE FUNCTION splits ...
- nuxt环境目录结构