题目详情
给你单链表的头指针 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
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/re… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
我们需要将橙色的部分进行反转
1.先定义一个虚拟头结点head,将它指向我们的真实头结点
2.定义一个
pre指针指向虚拟头结点
3.定义一个
cur指针指向pre指针的下一个结点
4.将
pre指针和cur指针向前移动,找到left结点
5.定义指针
con和tail,con指向pre指针所指向的结点,tail指向cur指针所指向的结点
con所指向的结点,将是我们部分链表反转后,部分链表头结点的前驱结点,tail则是部分链表反转后的尾结点
6.定义一个指针
next指向cur所指向结点的下一个结点,然后将cur所指向的结点指向pre所指向的结点,将pre指针移动到cur指针所在的位置,将cur指针移动到next指针的位置,直到pre指针指向n(right)结点
7.重复上述步骤,当
pre指针指向n(right)结点时,证明链表反转完成。
8.将
con指针所指向的结点指向pre指针指向的结点,tail指针指向cur指针指向的结点
9.最终链表
代码
/**
* 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;
}