查看原文
其他

554,反转链表 II

博哥 数据结构和算法 2022-05-19

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

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

问题描述



来源: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


头插法解决



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


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

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

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

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


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

再来看下代码

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}


总结



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


502,分隔链表的解决方式

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

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

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


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


你点的每个赞,我都认真当成了喜欢

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存