力扣链接
题目描述
给你单链表的头指针 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;
}
}
运行结果


776

被折叠的 条评论
为什么被折叠?



