力扣链接
题目描述
给你单链表的头指针 head
和两个整数 left
和 right
,其中 left <= right
。请你反转从位置 left
到位置 right
的链表节点,返回 反转后的链表 。
解题思路
在原有的链表上进行遍历反转,先找到left指向的节点并用l1指向该节点,并用l5记录l1的前一个节点,同时设置节点l2指向l1,l3指向下一个节点,用l2和l3参与循环遍历要反转的部分进行反转,最后将left的next指向right的next,left的前一个节点的next指向right。
初始记录:
循环反转:
-
初始化变量:
- 如果
left
和right
相等,则不需要反转任何部分,直接返回原链表head
。 - 定义
l1
为链表的头节点,l5
也是头节点,它将被用来指向left
位置前一个节点。
- 如果
-
定位反转起始点:
- 遍历链表直到
left
位置的前一个节点。这样,l5
指向left
位置前一个节点,而l1
指向left
位置的节点。
- 遍历链表直到
-
反转指定区间:
- 初始化
l2
为l1
,即反转开始的位置。 - 初始化
l3
为l2.next
,即反转区间的下一个节点。 - 使用循环来反转从
l2
到l3
的节点,直到反转完所有需要反转的节点。 - 循环次数为
right - left
。
- 初始化
-
更新反转后的链接关系:
- 如果
l5
不等于l1
,则更新l5.next
为l2
,即反转后的起始节点。 - 如果
l1
等于head
,则更新head
为l2
。 - 更新
l1.next
为反转区间的最后一个节点之后的节点l3
。
- 如果
解题代码
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
if (left == right) {//如果反转区间不存在,则直接返回原来的头节点
return head;
}
ListNode l1 = head; //l1先指向head,用来定位指向left
ListNode l5 = head; //l5先指向head,用来定位指向left的前一个节点
// 定位到反转起始点的前一个节点
for (int i = 1; i < left; i++) {
l5 = l1;
l1 = l1.next;
}
// 保存反转开始前的节点
ListNode l2 = l1;
ListNode l3 = l2.next;
int q = right - left;
// 反转指定区间
while (q > 0) {
ListNode l4 = l3.next;
l3.next = l2;
l2 = l3;
l3 = l4;
q--;
}
// 更新反转区间的前后连接
if (l5 != l1) {
//当l5不等于l1的时候,left不是head,可以将left的前一个节点的next指向right
l5.next = l2;
} else {//left是head,需要直接将head指向right
head = l2;
}
l1.next = l3;//left的next指向right的下一个节点
return head;
}
}