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

Pythonでソート済み配列が合計kのペアに分割できるか判定する方法

数値の配列ともう一つの数値 k が与えられたとき、その配列を「各ペアの合計が必ず k になるように」ペアへ分割できるかどうかを判定する問題を考えます。

たとえば、入力が arr = [1, 2, 3, 4, 5, 6]k = 7 の場合、出力は True になります。(2, 5)、(1, 6)、(3, 4) というペアを作れば、それぞれの合計がすべて 7 になるからです。

アルゴリズムの考え方

配列がすでにソートされていることを利用すると、両端から中央に向かって進める「二ポインタ(Two Pointers)」手法で効率的に判定できます。手順は以下の通りです。

  • n を配列の要素数とします。
  • n が奇数の場合、ペアを組み切れないため False を返します。
  • low = 0high = n - 1 として初期化します。
  • low < high の間、以下を繰り返します。
    • arr[low] + arr[high]k と等しくなければ False を返します。
    • low を 1 増やし、high を 1 減らします。
  • ループを抜けたら True を返します。

実装例

def solve(arr, k):
    n = len(arr)
    if n % 2 == 1:
        return False
    low = 0
    high = n - 1
    while low < high:
        if arr[low] + arr[high] != k:
            return False
        low = low + 1
        high = high - 1
    return True

arr = [1, 2, 3, 4, 5, 6]
k = 7
print(solve(arr, k))

入力

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

出力

True

計算量について

このアルゴリズムは配列を一度だけ走査するため、時間計算量は O(n) です。また、追加のメモリをほとんど使わないため、空間計算量は O(1) で済みます。

なお、この手法は配列がソート済みであることが前提です。未ソートの配列に対しては、あらかじめソートを行っておく必要があり、その場合は全体の計算量が O(n log n) になります。

  1. Pythonで配列を等しい合計のサブ配列に分割できる合計値を見つける方法

    整数の配列Aが与えられたとき、ある値sum[i]ごとに、配列を合計がsum[i]となる複数のサブ配列に分割できるような、すべての合計値を見つける必要があります。もし配列を等しい合計のサブ配列に分割できない場合は、-1を返します。 例えば、入力が A = [2, 4, 2, 2, 2, 4, 2, 6] の場合、出力は [6, 8, 12] になります。これは、配列を合計が6、8、12となるサブ配列にそれぞれ分割できるためです。具体的な分割例は以下の通りです。 合計6の場合: {2, 4}, {2, 2, 2}, {4, 2}, {6} 合計8の場合: {2, 4, 2}, {2, 2, 4}

  2. 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] となります。アルゴリズムの手順この問題を解くには、以下の手順に従います。i := 0、j := 0、end := Aの長さ − 1 を定義しますend >= 0 かつ A[end] が空(0)である間、end を 1 ずつ減らしていきますj が Bの長さ未満である間、以下の処理を繰