[これがコードテスト]21日目
▼▼緒論
今日私たちがしなければならないのは、前回学んだ順序探索とバイナリ探索を利用する問題です.
教材に収録された問題と標準におけるステップアルゴリズム−二分探索部分を解く.
▼▼本題
📍 [問題1]部品検索(教材収録)
この問題は、宣言されたリストに検索したい値があるかどうかを判断する問題です.
解決策はいろいろありますが、最も基本的なバイナリ検索アルゴリズムで解決しましょう.
まず、宣言されたリストを番号順に並べ替え、各売り場に探している部品があるかどうかを確認します.
このとき、売り場の部品が並んでいるので、バイナリ検索ができます.
'''
5
8 3 7 9 2
3
5 7 9
'''
import sys
def binary_search(array, target, start, end):
if start > end:
return False
mid = (start + end) // 2
if array[mid] == target:
return True
if array[mid] > target:
return binary_search(array, target, start, mid-1)
else:
return binary_search(array, target, mid+1, end)
n = int(input())
array = list(map(int, sys.stdin.readline().split()))
m = int(input())
target = list(map(int, sys.stdin.readline().split()))
for i in target:
if binary_search(array, i, 0, n-1):
print("yes", end=' ')
else:
print("no", end=' ')
👉🏽 no yes yes
したがって,このように問題を解くと,最悪の場合にはO(M x logN
回の時間的複雑度の演算が必要となり,理論的には最大2,000,000
回の演算が可能となる.逆に,N個の部品を並べ替えるのに要する時間的複雑さは
O(N x logN)
であり,理論的には最大約20,000,000
であり,より多くの演算が必要である.その結果、バイナリ検索を用いた解題方法では、時間的複雑さは、
O((M+N) x logN)
のソート数を含む.なお、この問題は
이진탐색
の他、계수정렬
、집합자료형
を用いて解くこともできる.계수정렬
は、すべての要素番号を含むサイズリストを作成し、リストのインデックスにアクセスして、番号の部品が売り場に存在するかどうかを決定するだけです.このとき、すべての要素は
n+1
の範囲内に制御される.'''
5
8 3 7 9 2
3
5 7 9
'''
import sys
n = int(input())
array = [0] * 100001
for i in input().split():
array[int(i)] = 1
m = int(input())
target = list(map(int, sys.stdin.readline().split()))
for i in target:
if array[i] == 1:
print('yes', end=' ')
else:
print('no', end=' ')
👉🏽 no yes yes
また、집합자료형
は、ある特定の数が一度発生したかどうかをチェックすればよいため、使用することができる.このような集合データ型は、特定のデータが存在するか否かを調べるのに非常に効果的である.
'''
5
8 3 7 9 2
3
5 7 9
'''
import sys
n = int(input())
array = set(map(int, sys.stdin.readline().split()))
m = int(input())
target = list(map(int, sys.stdin.readline().split()))
for i in target:
if i in array:
print('yes', end=' ')
else:
print('no', end=' ')
👉🏽 no yes yes
しかし、バイナリ検索で解決することもでき、アルゴリズムの問題の時間とメモリが非常に限られている場合は、他のアルゴリズムで解決することもできます.📍 [問題2]トッポッキ作り(教材収録)
典型的なバイナリ探索問題であり,
파라메트릭 서치(Parametric Search)
型の問題でもある.파라메트릭 서치(Parametric Search)
は、最適化問題を決定問題に変換して解決する技術である.詳細については、講義を参照してください.
たとえば、最適化問題が範囲内で条件を満たす最大値を見つけることを要求する場合、決定問題をバイナリ検索で解決し、範囲を縮小することができます.
符号化テストまたはプログラミングコンテストでは、通常、パラメトリック検索タイプはバイナリ検索を使用して解決される.
この問題の考えは以下の通りです.
適切な高さが見つかるまで、切断機高さ
H
まで切って条件を満たしますか?'''
4 6
19 15 10 17
'''
n, m = list(map(int, input().split()))
array = list(map(int, input().split()))
start = 0
end = max(array)
result = 0
while start <= end:
total = 0
mid = (start + end) // 2
for x in array:
if x > mid:
total += x - mid
if total < m:
end = mid - 1
else:
result = mid
start = mid + 1
print(result)
👉🏽 15
また、この問題は現在入手可能なトッポッキの量に応じて物差しの位置を決める必要があるため、再実現は面倒な作業になる可能性がある.したがって,この問題のようなパラメトリック探索問題タイプは,再帰アルゴリズムではなく繰返し文でバイナリ探索を実現すれば,より簡潔に問題を解くことができる.
📍 [問題3]伯俊-192(数字を探す)
質問する
問題は、与えられた単純数に対応する整数が存在するかどうかである.
H
と이진탐색
で問題を解いた.# 이진탐색(재귀)
'''
5
4 1 5 2 3
5
1 3 7 9 5
'''
import sys
def find_number(array, target, start, end):
if start > end:
return False
mid = (start + end) // 2
if array[mid] == target:
return True
elif array[mid] > target:
return find_number(array, target, start, mid-1)
else:
return find_number(array, target, mid+1, end)
n = int(input())
array = sorted(list(map(int, sys.stdin.readline().split())))
m = int(input())
target = list(map(int, sys.stdin.readline().split()))
for i in target:
if find_number(array, i, 0, n-1):
print(1)
else:
print(0)
👉🏽
1
1
0
0
0
1
# set 자료형
'''
5
4 1 5 2 3
5
1 3 7 9 5
'''
import sys
n = int(input())
array = set(map(int, sys.stdin.readline().split()))
m = int(input())
target = list(map(int, sys.stdin.readline().split()))
for i in target:
if i in array:
print(1)
else:
print(0)
👉🏽
1
1
0
0
0
1
どちらの問題も正解が得られたが,
set 자료형
資料型を用いた解答がset
の解答時間より3.8倍程度短縮されたことが確認できた.📍 [問題4]伯俊-10816(デジタルカード2)
質問する
この問題を実施するのは少し難しい.
明らかにバイナリ探索段階の問題であり,実際に問題を解く際にバイナリ探索を利用するのではなく,
이진탐색(재귀)
,딕셔너리
を用いて問題を解く.最初のパズルは
Counter
で、n_dict
と比べてarray
の中にarray
の値がなければ、1を加えて、n_dict
が何回加算されたかを知ることができます.例えば
n
です.最後に
{'6': 1, '3': 2, '2': 1, '10': 3, '-10': 2, '7': 1}
の値をtarget
と比較し、この値が存在する場合はn_dict
の値出力に設定し、そうでない場合は0に設定する.'''
10
6 3 2 10 10 10 -10 -10 7 3
8
10 9 -5 2 3 4 5 -10
'''
# 딕셔너리 선언 후 값 비교
import sys
n = int(input())
array = sys.stdin.readline().split()
n_dict = {}
for i in array:
if i in n_dict:
n_dict[i] = n_dict[i] + 1
else:
n_dict[i] = 1
m = int(input())
target = sys.stdin.readline().split()
for i in target:
if i in n_dict:
print(n_dict[i], end=' ')
else:
print(0, end=' ')
👉🏽 3 0 0 1 2 0 0 2
2つ目はn_dict[i]
関数を用いてCounter
値と比較し、target
内に存在する場合、いくつかの値を出力するプロセスである.'''
10
6 3 2 10 10 10 -10 -10 7 3
8
10 9 -5 2 3 4 5 -10
'''
# Counter 함수 사용
import sys
from collections import Counter
n = int(input())
array = sys.stdin.readline().split()
m = int(input())
target = sys.stdin.readline().split()
count = Counter(array)
for i in target:
if i in count:
print(count[i], end=' ')
else:
print(0, end=' ')
👉🏽 3 0 0 1 2 0 0 2
count
関数と比較して,Counter
資料型が発表され,メモリと時間が少し減少したことを示した.▼▼結論
今まで、私はすでにこの探求を学んで、完璧ではありませんが、これは概念を悟る時間です.
まだ
dict
を完全に理解していないので、白俊の他の問題は解決できません.もっと勉強して問題を解きます.
Reference
この問題について([これがコードテスト]21日目), 我々は、より多くの情報をここで見つけました https://velog.io/@abcd8637/이것이-코딩테스트다-21일차テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol