LeetCode (力锋) 92 問: リンク リストの逆引き II---ダブル ポインタ反復法で解く詳細なメモ付き

题目描述

単一リンクリストのヘッドポインタ 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       

运行结果

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/Just_do_myself/article/details/118364728