554,反转链表 II

History is apt to judge harshly those who sacrifice tomorrow for today. 

历史往往对那些为了今天而牺牲明天的人作出严厉的判决。

问题描述

来源:LeetCode第92题

难度:中等

 

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

554,反转链表 II

 

示例 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

 

头插法解决

之前讲过链表的全部反转《432,剑指 Offer-反转链表的3种方式,而这题只要求反转链表的部分节点,如果直接使用多个指针对需要反转的节点前后两两交换,也是可以解决的。

 

但这里我们使用一种更加容易理解的方式来解决,就是使用头插法,举个例子,比如我们要反转[1,2,3,4]

  • 第一步2插入到前面[2,1,3,4]

  • 第二步3插入到前面[3,2,1,4]

  • 第三步4插入到前面[4,3,2,1]

 

只需要把后面不停的往前面插入即可完成反转,这里以示例一为例画个图来看下

554,反转链表 II

554,反转链表 II

554,反转链表 II

再来看下代码

 1public ListNode reverseBetween(ListNode head, int m, int n) {
2    //为了方便处理,先创建一个哑节点,让他指向head
3    ListNode dummy = new ListNode(0);
4    dummy.next = head;
5
6    //记录开始反转节点的前一个节点
7    ListNode pre = dummy;
8    for (int i = 0; i < m - 1; i++) {
9        pre = pre.next;
10    }
11    //记录开始反转的节点,我们把它后面需要反转的的节点
12    //都移动到前面
13    ListNode cur = pre.next;
14
15    //采用头插法,把后面的节点都插入到前面
16    for (int i = 0; i < n - m; i++) {
17        ListNode next = cur.next;
18        cur.next = next.next;
19        next.next = pre.next;
20        pre.next = next;
21    }
22    return dummy.next;
23}

 

总结

链表的节点交换一般没什么难度,但如果不仔细很容易出错,对于链表的交换最好在纸上一步步把它画出来,这样才更容易理解。

 

554,反转链表 II

502,分隔链表的解决方式

466. 使用快慢指针把有序链表转换二叉搜索树

463. 判断回文链表的3种方式

432,剑指 Offer-反转链表的3种方式

 

 

截止到目前我已经写了500多道算法题了,为了方便大家阅读,我把部分算法题整理成了pdf文档,目前有1000多页,大家可以在公众号中回复关键字“pdf”即可获取下载链接。

 

554,反转链表 II你点的每个赞,我都认真当成了喜欢
上一篇:基于SpringBoot+AntDesign的快速开发平台,JeecgBoot 2.0.2 版本发布


下一篇:ffmpeg命令行获取RTSP流并每秒截取一张解码存储为jpg