[路飞]_leetcode_92.反转链表||

73 阅读1分钟

思考

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

示例: 给出的是 1->2->3->4->5, left = 2, right = 4

1 -> 2 -> 3 -> 4 -> 5
    left      right

1 -> 4 -> 3 -> 2 -> 5
  • 从示例中我们可以看出链表需要反转的节点是 2、3、4 ,
  • 我们可以将他们看成一个链表中的小链表 2->3->4 做反转链表操作 4->3->2
  • 然后原链表首尾拼接组成最终结果链表 1 4->3->2 5 => 1->4->3->2->5

解题思路

  1. 首先我们确定待反转小链表的头节点(由于小链表起始点可能为链表的第一个节点,所以我们需要虚拟头节点 hair 作为链表的第一个节点)
  2. 开始做反转操作,由于反转链表是到 right 位置停止, 所以链表反转操作需要做 right - left + 1 次(+1 是因为第一次要将头节点指向NUll)
  3. 最后将链表头节点、反转后的小链表、链表尾节点拼接。
设:
hair -> 1 -> 2 -> 3 -> 4 -> 5
       left          right

hair -> 1 -> 2 -> 3 -> 4 -> 5

hair  1 -> 2 -> 3 -> 4 -> 5

hair 4 -> 3 -> 2 -> 1  5

hair -> 4 -> 3 -> 2 -> 1 -> 5

代码

var reverse = function (head, cnt) {
    let pre = null, cur = head;
    while (cnt--) {
        let next = cur.next; 
        cur.next = pre;
        pre = cur;
        cur = next;
    }

    head.next = cur;
    return pre;
}

var reverseBetween = function(head, left, right) {
    // 如果链表为空,或者操作 left 和 right 位置相等,就返回原链表
    if (!head && left == right) return head;
    // 设置头节点来保存
    let hair = new ListNode(-1, head), pre = hair, cnt = right - left + 1;

    while (--left) {
        pre = pre.next;
    }

    pre.next = reverse(pre.next, cnt);

    return pre;
};