题目描述
単一リンクリストのヘッドポインタ head と、左と右の 2 つの整数 (左 <= 右) が与えられます。リンク リストのノードを左の位置から右の位置に反転し、反転したリンク リストを返してください。
示例
输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]
思路分析
この質問は、「リンク リストの反転」に関する前回の質問と非常によく似ています。前回は、リンク リスト全体が反転されました。今回は、間隔が取られ、その間隔内のリンク リストの一部が反転されます。このアイデアは、まず元のリンク リストから反転するリンク リストを取り出し、それを反転してから元のリンク リストに結合し直すことです。アイデアは比較的単純ですが、コードを実装するのはさらに面倒です。コードを参照してください。
代码
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode:
# 定义反转链表函数,此函数在“反转链表”那一题已经讲过
def reverse(node):
before = node
after = None
while before:
next = before.next
before.next = after
after = before
before = next
return after
# 接下来就是要找到要反转的链表部分
# 先定位反转链表部分的左节点
# 因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论
dummy_node = ListNode(-1)
dummy_node.next = head
pre = dummy_node
# 虚拟头节点向前移动 left - 1 步, 到达左节点的前一个结点
for i in range(left - 1):
pre = pre.next
# pre节点继续向前移动right - left + 1步,到达右节点
right_node = pre
for j in range(right - left + 1):
right_node = right_node.next
# 定位到左节点
left_node = pre.next
# 保留右节点右边的部分,用于后边反转之后的拼接
curr = right_node.next
# 切出反转链表部分
pre.next = None
right_node.next = None
# 反转链表
reversed_linklist = reverse(left_node)
# 将反转后的链表接入到原链表
pre.next = reversed_linklist
left_node.next = curr
return dummy_node.next
运行结果