トピック:
トピックリンク: https://leetcode-cn.com/problems/reverse-linked-list-ii/
問題解決のアイデア:
方法の一つ:新しいリストの配列+
タイトルは、元のノードを使用する必要がないので、これだけの行に対応するノード値を交換する必要があります
したがって、比較的単純なアプローチは、すべてのノードの値であり、配列に、対応する値が交換され、新しいリストを生成します
値の配列を交換する方法:
- MとNは添字の値に対応する切り替えられます
- 交換価値を継続し、N、M> = Nアップするまで右に左にM、
次のように示します:
方法2:再帰
再帰的な場合、実際には、同様の方法は、一方向関数リストで実装することができるプロセスを示した以下の通りであります:
変数:
- 左:左ノード値、グローバル変数を交換します
- 右:右は、ノード、再帰変数の値を交換します
- 停止:停止再帰するかどうか、グローバル変数
次のようにロジックを示します。
初めに、各再帰はない場合、開始ノードに移動するために放置した場合、右に移動するたびに1を左、右端ノードへ移動した場合ではない、右方への移動を
このとき、左右の停止は動いて、左の交換価値を、右、およびグローバル変数の左側には、前の再帰に戻って、右方向に移動させ、
右は再帰的変数、およびちょうどのみ交換価値であり、ノードの順序を変更しなかったので
したがって、前再帰に戻り、二重リンクリスト同様の機能PREVを達成するため、以下に示すように、代替ノードの前に右こと。
このとき、交換価値再び、バック以前の再帰に、右から左に移動します:
このとき、同一のノードに左右FOUND交換点は、真のグローバル変数ストップを変更する、再帰は、終了値の交換動作の全て上部値を停止します
コードの実装:
この方法の一つ:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode:
val_lst = []
while head:
val_lst.append(head.val)
head = head.next
m -= 1
n -= 1
while m < n:
val_lst[m], val_lst[n] = val_lst[n], val_lst[m]
m += 1
n -= 1
dummy = ListNode(0)
new_head = dummy
for val in val_lst:
new_head.next = ListNode(val)
new_head = new_head.next
return dummy.next
方法2:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode:
if not head or m >= n:
return head
left, right = head, head
stop = False
def reverse_help(right, m, n):
nonlocal left, stop
if n <= 1:
return
right = right.next
if m > 1:
left = left.next
reverse_help(right, m - 1, n - 1)
if not stop:
left.val, right.val = right.val, left.val
left = left.next
if left is right or left.next is right:
stop = True
reverse_help(right, m, n)
return head