正の整数の配列の中に、同じ整数があるかどうか探します。
ただし、整数の最大値は、配列のサイズより小さいものとします。
総当たり
総当たりで同じ整数があるか探します。
時間計算量は\( O(N^2) \) になります。
def find_duplicate_brute_force(array):
found_duplicates = set()
for i in range(len(array)):
for j in range(i+1, len(array)):
if array[i] == array[j]:
found_duplicates.add(array[i])
print('found_duplicates_BF', list(found_duplicates))
メモ配列
配列が見つかった際にメモを取る配列を使います。
時間計算量は\( O (N) \) になりますが、空間計算量も \( O (N) \) になります。
def find_duplicate_memo(array):
found_duplicates = set()
memo_array = [-1 for _ in range(len(array))]
for num in array:
if memo_array[num] == -1:
memo_array[num] = -memo_array[num]
else:
found_duplicates.add(num)
print('found_duplicates_MEMO', list(found_duplicates))
既存の配列をメモに使う
既存の配列を同じ数字が既にあるかのメモに使うことで、時間計算量\( O (N) \) 空間計算量\( O(1) \) を実現します。
具体的には、配列は正の整数のみで、最大値は配列のサイズより小さいという条件があるので、この配列自体をメモとして使うことができ、その整数をインデックスとする値に -1 をかけることで、既に存在することをメモします。
配列内の整数が負になってしまっても、絶対値をつけることで、常に正の整数に変換することができます。
def find_duplicate_abs(array):
found_duplicates = set()
for num in array:
if array[abs(num)] > 0:
array[abs(num)] = -array[abs(num)]
else:
found_duplicates.add(abs(num))
print('found_duplicates_ABS', list(found_duplicates))
まとめます。
def find_duplicate_brute_force(array):
found_duplicates = set()
for i in range(len(array)):
for j in range(i+1, len(array)):
if array[i] == array[j]:
found_duplicates.add(array[i])
print('found_duplicates_BF', list(found_duplicates))
def find_duplicate_memo(array):
found_duplicates = set()
memo_array = [-1 for _ in range(len(array))]
for num in array:
if memo_array[num] == -1:
memo_array[num] = -memo_array[num]
else:
found_duplicates.add(num)
print('found_duplicates_MEMO', list(found_duplicates))
def find_duplicate_abs(array):
found_duplicates = set()
for num in array:
if array[abs(num)] > 0:
array[abs(num)] = -array[abs(num)]
else:
found_duplicates.add(abs(num))
print('found_duplicates_ABS', list(found_duplicates))
if __name__ == '__main__':
array = [ 1, 2, 5, 1, 3, 4, 5]
# found_duplicates_BF [1, 5]
find_duplicate_brute_force(array)
# found_duplicates_MEMO [1, 5]
find_duplicate_memo(array)
# found_duplicates_ABS [1, 5]
find_duplicate_abs(array)