Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonで値kに基づいて連結リストのノードを並べ替えるプログラム

単方向連結リストとある値 k が与えられたとします。このとき、ノードを次の順序で並べ替える必要があります。まず値が k より小さいノードを先頭に集め、次に値が k と等しいノードを続け、最後にそれ以外(k より大きい)ノードを末尾に配置します。重要な制約として、ノード同士の相対的な順序は元のまま維持しなければなりません。

例えば、入力が L = [4, 3, 6, 6, 6, 10, 8]、k = 6 の場合、出力は [4, 3, 6, 6, 6, 10, 8] となります。4 と 3 は 6 未満なので先頭に、6 は 6 と等しいので中間に、10 と 8 は 6 より大きいため末尾に配置されますが、各グループ内の順序は元のリストのまま変わりません。

解決手順

この問題を解くには、以下の手順に従います。

  • 値 0 を持つダミーノード less_head を作成し、ポインタ less を less_head に設定する
  • 同様に、ダミーノード equal_head と greater_head を作成し、それぞれポインタ equal、greater を設定する
  • cur を先頭ノードに設定する
  • cur が null になるまで以下を繰り返す
    • cur の値が k より小さい場合:less の後ろに新しいノードを追加し、less を進める
    • cur の値が k より大きい場合:greater の後ろに新しいノードを追加し、greater を進める
    • それ以外の場合:equal の後ろに新しいノードを追加し、equal を進める
    • cur を次のノードに進める
  • less の next を equal_head の next につなぎ、equal の next を greater_head の next につなぐことで、3つのリストを1つに連結する
  • less_head の next を返す

ここでダミーノードを使う理由は、各グループの先頭への挿入処理を簡潔にし、null チェックを不要にするためです。また、このアルゴリズムはリストを一度だけ走査するため、計算量は O(n)、追加のメモリ使用量は O(n) で済みます。

理解を深めるために、以下の実装を見てみましょう。

実装例

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):
      less_head = less = ListNode(0)
      equal_head = equal = ListNode(0)
      greater_head = greater = ListNode(0)
      cur = node
      while cur:
         if cur.val < k:
            less.next = ListNode(cur.val)
            less = less.next
         elif cur.val > k:
            greater.next = ListNode(cur.val)
            greater = greater.next
         else:
            equal.next = ListNode(cur.val)
            equal = equal.next
         cur = cur.next
      less.next = equal_head.next
      equal.next = greater_head.next
      return less_head.next

ob = Solution()
L = make_list([4, 3, 6, 6, 6, 10, 8])
k = 6
print_list(ob.solve(L, k))

入力

[4, 3, 6, 6, 6, 10, 8], 6

出力

[4, 3, 6, 6, 6, 10, 8]
  1. プレフィックス(接頭辞)のリストに一致する文字列を抽出して出力するPythonプログラム

    プレフィックス(接頭辞)のリストに基づいて文字列を出力したい場合、リスト内包表記とany関数、そしてstartswithメソッドを組み合わせると、簡潔かつ効率的に実現できます。本記事では、具体的なコード例とともにその仕組みをわかりやすく解説します。コード例以下に実際の実装例を示します。my_list = [streek, greet, meet, leeks, mean] print(The list is : ) print(my_list) prefix_list = [st, ge, me, re] print(The prefix list is : ) print(prefix_

  2. Pythonで連結リストのm個のノードを保持した後にn個のノードを削除するプログラム

    始点ノードが「head」である連結リストと、2つの整数 m と n が与えられたとします。リストを走査しながら、先頭から数えて m 個のノードを残した直後の n 個のノードを削除する処理を、連結リストの末尾に到達するまで繰り返します。処理は head ノードから開始し、最後に変更後の連結リストを返します。今回扱う連結リストの構造は次のように定義されています。Node value : <整数値> next : <次のノードへのポインタ>例えば、入力が elements = [1, 2, 3, 4, 5, 6, 7, 8]、m = 3、n = 1 の場合、出