92. 反转链表 II | 反转链表 | 反转链表的前N个 | 反转部分链表

题目

92. 反转链表 II

解题思路

如果需要用递归来做这一道题目,需要理解反转链表和反转链表的前N个元素这两个题目。

  • 反转全部链表很容易理解,使用后序遍历,将元素 最后一个节点 返回,并且改变每一个元素的 next 指针
  • 反转前N个元素也并不难,和反转全部类似,但是特别注意的是记住后驱节点,也就是第 N+1 个节点。
  • 反转部分元素就是更进一步的综合体,对于反转部分来说就等于是反转全部,但是由于需要记住后驱节点,所以需要使用reverseN,等于是反转前N个节点。那么如何遍历到需要反转的节点呢?可以使用迭代或者递归,当触发条件时调用reverseN即可。

代码

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     val: number
 *     next: ListNode | null
 *     constructor(val?: number, next?: ListNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.next = (next===undefined ? null : next)
 *     }
 * }
 */


// 先考虑反转前N个节点,需要记住后驱节点
let successor = null;
function reverseN(head: ListNode | null, m: number): ListNode | null {
    if (m === 1) {
        successor = head.next; // 记录后驱节点
        return head;
    }
    const last = reverseN(head.next, m - 1);
    head.next.next = head;
    head.next = successor; // head.next = null; 定义的successor刚好满足
    return last;
}

// 如果已经实现了反转前N个节点,那么接下来该考虑的是如何使其在第m个节点时擦开始触发。
// 也就是说前M个不会变化,而m-n就会反转,n-len不会变化。
// 其实很好理解,还是可以通过遍历进行触发,使m每次减去1,当m===1时就代表需要触发反转了,此时对于当前的节点就是反转头节点,长度就是n-m
// 需要注意的是,可以使用m-1,n-1,来同步长度。之所以left===1,是因为包含left的节点需要反转。
function reverseBetween(head: ListNode | null, left: number, right: number): ListNode | null {
    if (left === 1) {
        return reverseN(head, right);
    }
    head.next = reverseBetween(head.next, left - 1, right - 1)
    return head;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值