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

Pythonでソート済み配列をマージする方法

問題の概要

2つのソート済み配列AとBが与えられたとき、それらをマージして1つのソート済み配列Cを作成することを考えます。なお、両者のサイズは異なっていても構いません。

例えば、A = [1,2,4,7]、B = [1,3,4,5,6,8] の場合、マージ後のリストCは [1,1,2,3,4,4,5,6,7,8] となります。

アルゴリズムの手順

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

  1. i := 0、j := 0、end := Aの長さ − 1 を定義します
  2. end >= 0 かつ A[end] が空(0)である間、end を 1 ずつ減らしていきます
  3. j が Bの長さ未満である間、以下の処理を繰り返します
    • i > end かつ A[i] が空の場合:A[i] := B[j] とし、j を 1 増やします
    • A[i] > B[j] の場合:shift(A, i) を実行したうえで A[i] := B[j] とし、end と j をそれぞれ 1 増やします
    • i を 1 増やします

shiftメソッドの動作

要素を挿入するために使われるshiftメソッドは、以下のように動作します。

  • num_arr と i を引数として受け取ります
  • j := num_arrの長さ − 1 を設定します
  • num_arr[j] が空(0)である間、j を 1 ずつ減らします
  • j >= i である間、num_arr[j+1] = num_arr[j] として要素を後ろにずらし、j を 1 ずつ減らします

このように、既存の要素を1つ後ろにシフトすることで、Bの要素を正しい位置に挿入できる仕組みです。

実装例

それでは、実際のコードを見て理解を深めましょう。

class Solution(object):
    def merge(self, nums1, m, nums2, n):
        i = 0
        j = 0
        end = len(nums1)-1
        while end>=0 and not nums1[end]:
            end-=1
        while j<len(nums2) :
            if i>end and not nums1[i]:
                nums1[i] = nums2[j]
                j+=1
            elif nums1[i]>nums2[j]:
                self.shift(nums1,i)
                nums1[i] = nums2[j]
                end+=1
                j+=1
            i+=1
        return nums1
    def shift(self,num,i):
        j = len(num)-1
        while not num[j]:
            j-=1
        while j>=i:
            num[j+1] = num[j]
            j-=1
ob = Solution()
print(ob.merge([1,2,3,0,0,0],3,[2,5,6],3))

入力

[1,2,3,0,0,0]
[2,5,6]

出力

[1, 2, 2, 3, 5, 6]

まとめ

このアプローチでは、nums1の末尾に確保された余分な領域(0で埋められた部分)を活用しながら、nums2の要素を順番に適切な位置へ挿入していきます。挿入が必要な場合はshiftメソッドで既存要素を後ろにずらすため、追加の配列を作らずにその場(in-place)でマージが完結する点が特徴です。計算量は最悪でもO(m×n)程度ですが、余分なメモリを使わないシンプルな手法として覚えておくと役立ちます。

  1. Pythonで挿入ソート(Insertion Sort)を実装する方法:アルゴリズムとサンプルコードを徹底解説

    この記事では、Python 3.x(およびそれ以前のバージョン)における挿入ソートの実装方法について詳しく解説します。挿入ソートは、トランプの手札を整理するイメージに近い、直感的で理解しやすいソートアルゴリズムです。挿入ソートのアルゴリズム挿入ソートは以下の手順で動作します。入力要素を順番に走査し、各反復ごとにソート済みの配列部分を少しずつ拡張していきます。現在注目している要素(キー)を、ソート済み部分の中で最も大きい値と比較します。キーがその値より大きければ、要素は元の位置のまま次の要素へ進みます。そうでなければ、ソート済み配列内の正しい位置を探し出し、そこへ移動させます。具体的には、ソート

  2. Pythonで学ぶ挿入ソート(Insertion Sort)の仕組みと実装方法

    この記事では、Python 3.xにおける挿入ソート(Insertion Sort)の基本的な考え方と、実際のコードによる実装方法をわかりやすく解説します。 挿入ソートのアルゴリズム 挿入ソートは、配列を「整列済みの部分」と「未整列の部分」に分け、未整列の要素を一つずつ取り出して、整列済み部分の正しい位置に挿入していくシンプルなソート手法です。処理の手順は以下の通りです。 1. 各反復ごとに整列済みの配列を少しずつ拡大しながら、入力要素を走査する。 2. 現在の要素(キー)を、整列済み配列内の最大値と比較する。 3. キーがその最大値より大きければ、要素はそのままの位置に置かれ、 次の要