[路飞] 92. 反转链表 II

124 阅读2分钟

题目详情

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

示例 1:

12121212.jpg

输入: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) 链接:leetcode-cn.com/problems/re… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

我们需要将橙色的部分进行反转

1.先定义一个虚拟头结点head,将它指向我们的真实头结点 1645894233(1).jpg 2.定义一个pre指针指向虚拟头结点 1645894297(1).jpg 3.定义一个cur指针指向pre指针的下一个结点 1645894338(1).jpg 4.将pre指针和cur指针向前移动,找到left结点

1645970663(1).jpg 5.定义指针contailcon指向pre指针所指向的结点,tail指向cur指针所指向的结点 con所指向的结点,将是我们部分链表反转后,部分链表头结点的前驱结点,tail则是部分链表反转后的尾结点

1645971004(1).jpg 6.定义一个指针next指向cur所指向结点的下一个结点,然后将cur所指向的结点指向pre所指向的结点,将pre指针移动到cur指针所在的位置,将cur指针移动到next指针的位置,直到pre指针指向n(right)结点

1645971442(1).jpg

1645972388(1).jpg

1645972945(1).jpg 7.重复上述步骤,当pre指针指向n(right)结点时,证明链表反转完成。

1645973415(1).jpg 8.将con指针所指向的结点指向pre指针指向的结点,tail指针指向cur指针指向的结点

1645973664(1).jpg 9.最终链表

1645973850(1).jpg

代码

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} left
 * @param {number} right
 * @return {ListNode}
 */
var reverseBetween = function(head, left, right) {
    if(!head) return null;
    //定义虚拟头结点ret,pre:指针指向虚拟头结点,cnt:链表翻转次数
    let ret=new ListNode(0,head),pre=ret,cnt=right-left+1;
    //找到反转区域前一个头结点pre的位置
    while(--left){
        pre=pre.next;
    }
    //让反转区域的前一个节点指向反转后的头结点
    pre.next=reverse(pre.next,cnt);
    return ret.next;
     }
    var reverse=function(head,n){
        let pre=null,cur=head;
        //n为待反转区域次数
        while(n--){
            [cur.next,pre,cur]=[pre,cur,cur.next]
        }
        //最初的头结点指向right节点的后一个节点
        head.next=cur;
        return pre;
   
}