Pythonで配列が指定範囲のすべての要素を含んでいるかどうかを判定する方法
nums という配列と、2つの整数 x、y があるとします。この2つの数値は範囲 [x, y] を定義しており、配列がこの範囲内のすべての要素を含んでいるかどうかを判定する必要があります。
たとえば、入力が nums = [5,8,9,6,3,2,4]、x = 2、y = 6 の場合、範囲内の要素 [2,3,4,5,6] がすべて配列に存在するため、出力は True になります。
解決のためのアプローチ
この問題は、配列の要素の符号を反転させて「訪問済み」のマークとして利用することで、追加のメモリを使わずに効率的に解くことができます。手順は以下の通りです。
temp_range := y - xを計算します。- 0 から配列
numsのサイズまで繰り返します。|nums[i]|がx以上かつy以下である場合:z := |nums[i]| - xを計算します。nums[z] > 0であれば、nums[z] := -nums[z]として符号を反転し、その値が存在することを記録します。
- カウンタ
cnt := 0を初期化します。 - 0 から
temp_rangeまで繰り返します。iが配列のサイズ以上になった場合はループを抜けます。nums[i] > 0であれば、範囲内の値が欠けていることを意味するため False を返します。- それ以外の場合は
cnt := cnt + 1とします。
cntが(temp_range + 1)と等しくなければ False を返します。- すべてのチェックを通過すれば True を返します。
このアルゴリズムの計算量は O(n)、追加のメモリ使用量は O(1) であり、非常に効率的です。ただし、配列の内容が書き換えられる点や、範囲内の値がインデックスの範囲に収まっている必要がある点には注意してください。
実装例
それでは、実際のコードを見て理解を深めましょう。
def solve(nums, x, y):
temp_range = y - x
# 範囲内の各値について、対応する位置の符号を反転してマークする
for i in range(0, len(nums)):
if abs(nums[i]) >= x and abs(nums[i]) <= y:
z = abs(nums[i]) - x
if nums[z] > 0:
nums[z] = nums[z] * -1
cnt = 0
# 範囲内のすべての位置がマークされているか確認する
for i in range(0, temp_range + 1):
if i >= len(nums):
break
if nums[i] > 0:
return False
else:
cnt += 1
if cnt != temp_range + 1:
return False
return True
nums = [5,8,9,6,3,2,4]
x = 2
y = 6
print(solve(nums, x, y))
入力
[5,8,9,6,3,2,4], 2, 6
出力
True
このように、符号反転のテクニックを活用することで、セットや辞書などの補助データ構造を使わずに、範囲内の全要素の存在チェックを1回の走査で行うことができます。
-
Pythonで配列から1つの要素を削除して「良い配列」になるインデックスをすべて見つける方法
問題の概要 数値の配列 A が与えられたとき、i 番目の要素を削除した後に「良い配列(good array)」となるような、すべてのインデックスを見つける必要があります。ここでの条件は以下の通りです。 良い配列とは、配列内のある要素が、それ以外のすべての要素の合計と等しい配列のことです。 インデックスは 1 始まり(1-based)で表します。 たとえば、入力が [10, 4, 6, 2] の場合、出力は [1, 4] になります。 A[1](=10)を削除すると、配列は [4, 6, 2] となり、6 = 4 + 2 が成立するため良い配列です。 A[4](=2)を削除すると、配列は
-
【Python】文字列がすべてユニークな文字で構成されているか判定する方法
本記事では、与えられた文字列に含まれる文字がすべて一意(ユニーク)であるかどうかを判定するPythonプログラムについて、その解法とアプローチをわかりやすく解説します。 問題の概要 文字列が入力として与えられたとき、その文字列に含まれるすべての文字が重複なく一意であるかどうかを判定します。たとえば「abcde」はすべて異なる文字で構成されているためTrue、「tutorialspoint」のように同じ文字が複数回出現する場合はFalseとなります。 アプローチ この問題は、以下のような手順で効率的に解くことができます。 ブール値の配列を用意する: 各インデックス i が「アルファベット(AS