一、题目描述
给你单链表的头指针 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
二、思路分析
可以使用头插法,在需要反转的区间里,每遍历到一个节点,让这个新节点来到反转部分的起始位置。创建四个指针,resultNode、preNode、currentNode、nextNode来记录翻转过程。
其中:
resultNode:虚拟节点,resultNode.next 指向头节点,用来返回链表结果的;
preNode:永远指向 left 前一个节点,即待翻转区域的头节点,在循环过程中不变;
currentNode:永远指向待翻转的节点;
nextNode:永远指向 currentNode 的下一个节点,并跟着 currentNode 变化而变化
三、代码参考
1、Java
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
// 用来返回链表结果的节点,为虚拟节点,指向链表的头节点
ListNode resultNode = new ListNode(0, head);
// 创建 preNode 指针永远指向待翻转的节点的前一个
ListNode preNode = resultNode;
// 先通过循环将 preNode 指针移到 left 前一个,即 preNode.next 指向 left 这个待翻转节点
for(int i = 0; i < left - 1; i++){
preNode = preNode.next;
}
// 创建 currentNode 指针,这个指针指向待翻转节点
ListNode currentNode = preNode.next;
ListNode nextNode;
// 遍历链表节点,遍历次数为 right - left 的差值
for(int i = 0; i < right - left; i++){
// 永远指向 currentNode 的下一个节点,循环中需要不断变化
nextNode = currentNode.next;
// 1、先将 currentNode.next 指向 nextNode.next 节点
currentNode.next = nextNode.next;
// 2、再将 nextNode.next 指向 preNode.next 节点
nextNode.next = preNode.next;
// 3、最后将 preNode.next 指向 nextNode 节点,则完成头插
preNode.next = nextNode;
}
// 返回链表结果
return resultNode.next;
}
}
2、Python
class Solution(object):
def reverseBetween(self, head, left, right):
# 用来返回链表结果的节点,为虚拟节点,指向链表的头节点
resultNode = ListNode(0, head)
# 创建 preNode 指针永远指向待翻转的节点的前一个
preNode = resultNode
# 先通过循环将 preNode 指针移到 left 前一个,即 preNode.next 指向 left 这个待翻转节点
for i in range(left - 1):
preNode = preNode.next
# 创建 currentNode 指针,这个指针指向待翻转节点
currentNode = preNode.next
# 遍历链表节点,遍历次数为 right - left 的差值
for i in range(right - left):
# 永远指向 currentNode 的下一个节点,循环中需要不断变化
nextNode = currentNode.next
# 1、先将 currentNode.next 指向 nextNode.next 节点
currentNode.next = nextNode.next
# 2、再将 nextNode.next 指向 preNode.next 节点
nextNode.next = preNode.next
# 3、最后将 preNode.next 指向 nextNode 节点,则完成头插
preNode.next = nextNode
# 返回链表结果
return resultNode.next