Pythonで配列のサイズkのすべてのセグメントにキーが存在するか確認する方法
問題の概要
N個の要素を持つ配列A、探索対象の値p、そしてセグメントサイズkが与えられます。このとき、配列Aをサイズkごとのセグメントに区切った場合に、すべてのセグメントにキーpが含まれているかどうかを判定するのが目的です。
たとえば、入力が次のとおりだったとします。
- A = [4, 6, 3, 5, 10, 4, 2, 8, 4, 12, 13, 4]
- p = 4
- k = 3
この場合、配列は [4, 6, 3]、[5, 10, 4]、[2, 8, 4]、[12, 13, 4] の4つのセグメントに分けられ、それぞれに値4が含まれているため、出力は True になります。
アルゴリズムの手順
この問題は、以下の手順に沿って解くことができます。
- 外側のループ変数 i を 0 で初期化します。
- i < n の間、次の処理を繰り返します。
- 内側のループ変数 j を 0 で初期化し、j < k の間、arr[j + i] が p と一致するかどうかを順番に調べます。
- 一致する要素が見つかったら、break で内側のループを抜けます。
- 内側のループが終了した時点で j == k になっている場合、そのセグメントには p が存在しないため、False を返します。
- i を k ずつ増やして、次のセグメントへ進みます。
- ループ終了後に i == n であれば、配列がちょうどセグメント単位で処理し切れたことを意味するので、True を返します。
- 余りの要素(最後の不完全なセグメント)が存在する場合は、j = i − k から配列の末尾まで走査し、p が存在するかどうかを確認します。
- 最後まで見つからなければ False を、見つかれば True を返します。
実装例
理解を深めるために、実際のPythonコードを見てみましょう。
def key_in_segment_k(arr, p, k, n) :
i = 0
while i < n :
j = 0
while j < k :
if arr[j + i] == p :
break
j += 1
if j == k :
return False
i = i + k
if i == n :
return True
j = i - k
while j < n :
if arr[j] == p :
break
j += 1
if j == n :
return False
return True
arr = [4, 6, 3, 5, 10, 4, 2, 8, 4, 12, 13, 4]
p, k = 4, 3
n = len(arr)
print(key_in_segment_k(arr, p, k, n))入力
[4, 6, 3, 5, 10, 4, 2, 8, 4, 12, 13, 4]
出力
True
計算量について
このアルゴリズムの時間計算量は O(n)、空間計算量は O(1) です。各要素は高々一度だけ比較されるため、配列全体を線形時間で効率的に処理できます。なお、この実装は配列の長さ n がセグメントサイズ k で割り切れるケースを基本としており、余りのセグメントが発生する場合は後半の走査処理がそれに対応します。
-
Pythonですべてのペアが「良いペア」となる部分列の最大サイズを求めるプログラム
サイズ n の数列 nums が与えられます。この中から、任意のペア (p, q) がすべて「良いペア(nice pair)」となるような nums の部分列の最大サイズを求めることを考えます。あるペアが「良いペア」であるとは、次の条件のうち少なくとも1つを満たす場合を指します。p が持つ相異なる素因数の個数の偶奇が、q のそれと一致する。たとえば 18 の相異なる素因数は 2 と 3 の2つです。p の正の約数の総和の偶奇が、q のそれと一致する。たとえば、入力が nums = [2,3,6,8] のとき、出力は 3 になります。解き方の手順この問題を解くには、次の手順に従います。n :=
-
Pythonで配列が二分探索木(BST)の中間順巡回を表しているかどうかを判定する方法
数値の配列 nums が与えられたとき、その配列がある二分探索木(Binary Search Tree)を中間順巡回(inorder traversal)した結果と一致する順序で要素を保持しているかどうかを判定します。例えば、入力が nums = [5, 8, 15, 18, 20, 26, 39] の場合、この配列は以下の二分探索木を中間順巡回した結果と一致するため、出力は True になります。解法のポイントここで重要な性質があります。それは、二分探索木を中間順巡回すると、必ず昇順にソートされた要素列が得られるというものです。したがって、この問題は「配列が昇順に並んでいるかどうかを確認する