给你单链表的头指针 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
思路
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
//加个表头
ListNode res = new ListNode(-1);
res.next = head;
//前序节点
ListNode pre = res;
//当前节点
ListNode cur = head;
//找到left
for (int i = 1; i < left; i++) {
pre = cur;
cur = cur.next;
}
//从left反转到right
for (int i = left; i < right; i++) {
ListNode temp = cur.next;
cur.next = temp.next;
temp.next = pre.next;
pre.next = temp;
}
//返回去掉表头
return res.next;
}
}
-
ListNode
类定义了一个单链表的节点,包含一个整数值val
和一个指向下一个节点的指针next
。 -
reverseBetween
方法是解决问题的核心函数。它接受三个参数:head
表示链表的头节点,left
表示反转的起始位置,right
表示反转的结束位置。函数返回反转部分后的链表头节点。 -
在函数开始处,创建了一个新的头节点
res
,其值为 -1,并将其next
指针指向原始头节点head
。这是为了处理头节点可能被反转的情况。 -
定义了两个指针
pre
和cur
,分别表示反转部分的前一个节点和当前节点,初始化时分别指向新的头节点res
和原始头节点head
。 -
使用一个循环找到反转部分的起始节点。迭代直到
i
的值等于left
,在循环中,将pre
移动到cur
,cur
移动到下一个节点,直到达到左边界。 -
使用另一个循环来实现链表部分的反转。迭代直到
i
的值等于right - 1
,在循环中,将temp
指向cur.next
(即要移动的节点),然后更新cur.next
指向temp.next
,使得temp
从链表中脱离出来,接着将temp
的next
指针指向pre.next
,然后将pre.next
指向temp
,即将temp
插入到pre
和pre.next
之间。这样就完成了链表的反转。 -
最后,返回去掉了新头节点
res
的链表。因为res
实际上是在原链表头节点之前添加了一个辅助节点,所以我们返回res.next
即可得到反转后的链表头节点。