Pythonで連結リストをk個ずつのグループに分けて反転させる方法
片方向連結リストと整数 k が与えられたとき、リストを先頭から k 個ずつの連続するグループに分割し、それぞれのグループ内でノードの並びを反転させる問題を考えます。
たとえば、入力が List = [1,2,3,4,5,6,7,8,9,10]、k = 3 の場合、出力は [3, 2, 1, 6, 5, 4, 9, 8, 7, 10] となります。3個ごとに区切られた各グループが逆順になっており、余った要素(この例では最後の 10)は元の順序のまま保持される点に注目してください。
アルゴリズムの流れ
この問題を解くには、次の手順に従います。
- 値 0 を持つダミーノード tmp を作成し、tmp の次に元の先頭ノードを接続します。
- prev := null、curr := null として初期化します。
- lp(前グループの末尾)、lc(現在グループの先頭)を設定します。
- カウンタ cnt := k とします。
- curr が null でない限り、以下を繰り返します。
- prev を null にリセットします。
- cnt > 0 かつ curr が null でない限り、以下を繰り返します。
- following := curr の次のノード
- curr のポインタを prev に向けます(リンクの反転)
- prev := curr、curr := following と更新
- cnt を 1 減らします。
- 前グループの末尾 lp の次を prev(反転後のグループの新しい先頭)につなぎ、lc の次を curr につなぎます。
- lp := lc、lc := curr と更新します。
- cnt を k に戻します。
- 最後に tmp の次のノード(新しい先頭)を返します。
それでは、理解を深めるために実際の実装を見てみましょう。
実装例
class ListNode:
def __init__(self, data, next=None):
self.val = data
self.next = next
def make_list(elements):
head = ListNode(elements[0])
for element in elements[1:]:
ptr = head
while ptr.next:
ptr = ptr.next
ptr.next = ListNode(element)
return head
def print_list(head):
ptr = head
print('[', end='')
while ptr:
print(ptr.val, end=', ')
ptr = ptr.next
print(']')
class Solution:
def solve(self, node, k):
tmp = ListNode(0)
tmp.next = node
prev, curr = None, node
lp, lc = tmp, curr
cnt = k
while curr:
prev = None
while cnt > 0 and curr:
following = curr.next
curr.next = prev
prev, curr = curr, following
cnt -= 1
lp.next, lc.next = prev, curr
lp, lc = lc, curr
cnt = k
return tmp.next
ob = Solution()
head = make_list([1,2,3,4,5,6,7,8,9,10])
print_list(ob.solve(head, 3))
入力
[1,2,3,4,5,6,7,8,9,10], 3
出力
[3, 2, 1, 6, 5, 4, 9, 8, 7, 10]
この手法では、ダミーノードを使うことで先頭グループの扱いを統一でき、各グループ内でポインタを順次付け替えることで O(n) の時間計算量で反転を実現できます。追加のデータ構造が必要ないため、空間計算量も O(1) に抑えられるのが大きな利点です。
-
文中の各単語を逆順に並べ替えるPythonプログラムの書き方
この記事では、Pythonの組み込み関数を使って、文の中の各単語を逆順にする方法を解説します。処理の流れはシンプルで、まず文を単語のリストに分割し、次に各単語を反転させて新しいリストを作成し(ここではリスト内包表記を活用)、最後にそのリストを結合して新しい文を生成します。 実行例 入力 :: PYTHON PROGRAM 出力 :: NOHTYP MARGORP アルゴリズム ステップ1 : 文を入力し、変数 s に格納する。 ステップ2 : 文を単語のリストに分割する。 w = s.split( ) ステップ3 : 各単語を反転させ、新しい単語リスト nw を作成する。 ステップ
-
Pythonで指定したサイズのグループごとに配列を反転させるプログラム
この記事では、ユーザーが入力した配列とグループのサイズをもとに、指定されたサイズごとに配列を反転させるPythonプログラムを解説します。 基本的な考え方はシンプルです。まず、配列をグループサイズ(p)ずつの部分配列に分割し、各部分配列を個別に反転させます。 p が n の倍数でない場合: 最後のグループは p 個未満の要素が余りますが、その余った要素も含めてすべて反転します。 p = 1 の場合: 各要素は単独のグループとなるため、配列は元の順序のまま変化しません。 p ≥ n の場合: 配列全体がひとつのグループとして扱われ、すべての要素が一括で反転されます。 アルゴリズム 以下は、こ