-
์๊ฐ์ ํ 1์ด๋น ์ฝ 2์ฒ๋ง๋ฒ~1์ต๋ฒ ์ฐ์ฐ
-
O(1)
- List์์
pop() - deque์์
pop()/popleft()/append()/appendleft() - PriorityQueue์์
get() - Dictionary(ํด์ ํ
์ด๋ธ)์์
in/del์ฐ์ฐ - Set์์
in/del์ฐ์ฐ
- List์์
-
O(logn)
- PriorityQueue์์
put() - heapq์์
heappush()/heappop() - ์ด์ง ํ์(Binary Search)
- PriorityQueue์์
-
O(n)
- List์์
in์ฐ์ฐ - List์์
pop(n) - ํฌ ํฌ์ธํฐ
- List์์
-
O(nlogn)
sort(),sorted()- ๋ณํฉ ์ ๋ ฌ, ํต ์ ๋ ฌ
-
O(n^2)
- ๋ฒ๋ธ ์ ๋ ฌ
-
O(2^n)
-
O(n!)
์ ๋ ฅ ๋ฐ๊ธฐ
-
์ ์ 1๊ฐ
num = int(input()) -
์ ์ 2๊ฐ ์ด์
num1, num2 = map(int, input().split()) -
์ฌํ ๋ฒ์
lis = list(map(int, input().split())) # 1 2 3 4 5 -> [1, 2, 3, 4, 5]
lis = list(map(int, input())) # 12345 -> [1, 2, 3, 4, 5]
lis = input().split() # a b c d e -> ['a', 'b', 'c', 'd', 'e']
lis = [] for _ in range(row): # ํ ์ lis.append(list(map(int, input().split()))) # 1 2 3 # 4 5 6 # -> # [[1, 2, 3], [4, 5, 6]]
-
ํจ์จ์ ์ผ๋ก ์ ๋ ฅ ๋ฐ๊ธฐ
# ์ฌ๋ฌ ์ค์ ๋ฐ๋ณตํด์ ์ ๋ ฅ๋ฐ์์ผํ ๋, input()์ ์ฌ์ฉํ๋ฉด ์๊ฐ์ด๊ณผ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฏ๋ก sys.stdin.readline()๋ฅผ ์ฌ์ฉ import sys data = sys.stdin.readline().rstrip() # rstrip()์ ๊ฐํ๋ฌธ์๋ฅผ ์ ๊ฑฐํ๊ธฐ ์ํจ
import sys input = sys.stdin.readline data = input()
-
+ํจ์จ์ ์ผ๋ก ์ถ๋ ฅํ๊ธฐ
- ์ฃผ์)
print()์์ ์ ์๋ฅผ ๋ฃ์ผ๋ฉด TypeError๊ฐ ๋ฐ์ํ๋ฏ๋กstr()๋ก ํ๋ณํ ํด์ค์ผํจ
import sys print = sys.stdout.write print('๋ด์ฉ')
- ์ฃผ์)
Python ๊ธฐ๋ณธ ๋ฌธ๋ฒ
- ์์ฃผ ์ฐ๋ ํจ์
-
๋ฆฌ์คํธ.insert(idx, value) -
์ฌ๊ทํจ์์ ์ต๋ ํธ์ถ ํ์ ์ ํ ๋๋ฆฌ๊ธฐ (default: 3000)
import sys sys.setrecursionlimit(10000)
-
๋ฌธ์์ด์ ํน์ ์ธ๋ฑ์ค์์๋ถํฐ ์ฐพ๊ธฐ
- ๊ฒ์์ ํน์ ์ธ๋ฑ์ค์์๋ถํฐ ํ์ง๋ง, ๋ฐํ ๊ฐ์ ์๋ณธ ๋ฌธ์์ด์์์ ์ธ๋ฑ์ค๋ฅผ ๋ฐํํ๋ค!
- ๋ฆฌ์คํธ์๋ ์ด ๊ธฐ๋ฅ์ด ์์
s = 'abcba' s.find('a') # 0 ('abcba'์ ์์์๋ถํฐ ๊ฒ์) s.find('a', 1) # 4 ('bcba'์ ์์์๋ถํฐ ๊ฒ์) s.rfind('a') # 4 ('abcba'์ ๋ค์์๋ถํฐ ๊ฒ์) s.rfind('a', 1) # 4 ('bcba'์ ๋ค์์๋ถํฐ ๊ฒ์)
-
-
์ง๋ฒ ๋ณํํ๊ธฐ
-
n์ง๋ฒ โ 10์ง๋ฒ ๋ณํ:
int(์ ๋ฌธ์์ด, n)print(int('1000', 2)) # 8
-
10์ง๋ฒ โ 2์ง๋ฒ ๋ณํ:
bin()num = 8 print(bin(num)) # '0b1000' print(bin(num)[2:]) # '1000
-
-
Set ์๋ฃํ
- ๋น Set ์์ฑ:
S = set()- ์ฃผ์)
S = {}๋ก ์ฐ๋ฉด Dictionary ์๋ฃํ์ผ๋ก ์ธ์ํจ
- ์ฃผ์)
- ์ฑ์์ง Set ์์ฑ:
S = {1,2,3} - ์์ ์ถ๊ฐ:
S.add()- ์ค๋ณต๋ ์์๊ฐ ๋ค์ด์ค๋ฉด ์ค๋ณต ์ ๊ฑฐํจ
- ์์๊ฐ ์์ผ๋ฏ๋ก ์์๊ฐ ์ ์ง๋์ง ์์
- ์์ ์ ๊ฑฐ:
S.remove()- ํด๋น ์์๊ฐ ์กด์ฌํ์ง ์์ผ๋ฉด Error ๋ฐ์
- Error ๋ฐ์ํ์ง ์๊ฒ ์ ๊ฑฐํ๋ ค๋ฉด
S.discard()์ฌ์ฉ
in์ฐ์ฐ ๊ฐ๋ฅ (์๊ฐ๋ณต์ก๋: O(1))- ์งํฉ ์ฐ์ฐ
- ํฉ์งํฉ:
S1 | S2 - ๊ต์งํฉ:
S1 & S2 - ์ฐจ์งํฉ:
S1 - S2- ๋ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ:
S1.difference_update(S2)
- ๋ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ:
- ํฉ์งํฉ:
- ๋น Set ์์ฑ:
- Slicing
- ๋ฆฌ์คํธ ์ฌ๋ผ์ด์ฑ ๊ฒฐ๊ณผ ๊ฐ์ ๋ฆฌ์คํธํ
- ์ค์ ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์์!
lis = [2,4,6,8] lis[3:10] # [8]
-
List Comprehension
- ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
arr = [1,2,3,4,5] result = [x for x in arr] # [1,2,3,4,5]
- if๋ฌธ ์ฌ์ฉ
arr = [1,2,3,4,5] result = [x for x in arr if x < 3] # [1,2]
- if ~ else๋ฌธ ์ฌ์ฉ
arr = [5,3,2,7,1] result = ['small' if x < 3 else 'big' for x in arr] # ['big', 'big', 'small', 'big', 'small']
- ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
-
๋ฆฌ์คํธ โ ๋ฌธ์์ด
: ๋ฌธ์์ด์ด ๋ค์ด ์๋ ๋ฆฌ์คํธ๋ฅผ ํ๋์ ๋ฌธ์์ด๋ก ํฉ์น๊ธฐ
''.join(๋ฆฌ์คํธ)
-
์ ๋ ฌ (Sorting)
-
๋ฆฌ์คํธ ์ ๋ ฌ
๋ฆฌ์คํธ.sort(): ์๋ ๊ฒ ๋ฐ๋
sorted(๋ฆฌ์คํธ): ์๋ ๊ฒ ๋ฐ๋์ง ์์-
์์1
lis = ["5e", "3a", "1a"]์ผ ๋,-
ํํ์ 1๊ฐ: ์ฃผ์ด์ง ํํ์์ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌ
- ์ฃผ์ด์ง ํํ์์ด ๋์ผํ ๊ฐ๋ค๋ผ๋ฆฌ๋ ๊ธฐ์กด ์์ ์ ์ง
sorted(lis, key=lambda x: x[1]) # ['3a', '1a', '5e'] - ์ฃผ์ด์ง ํํ์์ด ๋์ผํ ๊ฐ๋ค๋ผ๋ฆฌ๋ ๊ธฐ์กด ์์ ์ ์ง
-
ํํ์ 2๊ฐ: ์ฒซ ๋ฒ์งธ ํํ์์ ์ฐ์ ์ผ๋ก ํ๊ณ , ์ฒซ ๋ฒ์งธ ํํ์์ด ๊ฐ์ ๊ฒฝ์ฐ ๋ ๋ฒ์งธ ํํ์์ ๋ฐ๋ผ ์ ๋ ฌ
sorted(lis, key=lambda x: (x[1], x[0])) # ['1a', '3a', '5e']
-
-
์์2
lis = ['eee', 'c', 'dd', 'bb', 'aaa']์ผ ๋,sorted(lis, key=lambda x: len(x))
sorted(lis, key=len) # ['c', 'dd', 'bb', 'eee', 'aaa']sorted(lis, key=lambda x: (len(x), x)) # ['c', 'bb', 'dd', 'aaa', 'eee']sorted(lis, key=lambda x: (-len(x), x)) # ['aaa', 'eee', 'bb', 'dd', 'c']- ์ซ์ ํ์
์ ๋ํด์๋
-๋ฅผ ๋ถ์ฌ์ ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ์ ํ ์ ์์!
- ์ซ์ ํ์
์ ๋ํด์๋
-
-
๋์ ๋๋ฆฌ ์ ๋ ฌ
sorted(๋์ ๋๋ฆฌ): ์๋ ๊ฒ ๋ฐ๋์ง ์์-
์์
d = {'b': 3, 'c': 1, 'a': 2}์ผ ๋,sorted(d)
sorted(d.keys()) # ['a', 'b', 'c']sorted(d.items())
sorted(d.items(), key=lambda x: x[0]) # [('a', 2), ('b', 3), ('c', 1)]sorted(d.values()) # [1, 2, 3]sorted(d.items(), key=lambda x: x[1]) # [('c', 1), ('a', 2), ('b', 3)]sorted(d.items(), key=lambda x: (x[0], x[1])) # [('a', 2), ('b', 3), ('c', 1)]
-
-
๋ฌธ์์ด ์ ๋ ฌ
sorted(๋ฌธ์์ด): ์๋ ๊ฒ ๋ฐ๋์ง ์์- ์์:
sorted('zebra') # ['a', 'b', 'e', 'r', 'z']
- ์์:
-
-
๋ฌธ์์ด์ด ์ํ๋ฒณ/์ซ์์ธ์ง ํ์ธ
-
์ซ์๋ก๋ง ์ด๋ฃจ์ด์ ธ ์๋์ง ํ์ธ:
๋ฌธ์์ด.isdecimal() -
์ํ๋ฒณ์ผ๋ก๋ง ์ด๋ฃจ์ด์ ธ ์๋์ง ํ์ธ:
๋ฌธ์์ด.isalpha() -
์ซ์+์ํ๋ฒณ์ผ๋ก ์ด๋ฃจ์ด์ ธ ์๋์ง ํ์ธ:
๋ฌธ์์ด.isalnum()
-
- XOR ์ฐ์ฐ
-
^์ฐ์ฐ์ intํ ๋ณ์์๋ง ๊ฐ๋ฅ, '0111'๊ณผ ๊ฐ์ ๋ฌธ์์ด์๋ ๋ถ๊ฐ# ๊ฐ์ด 0์ด๋ฉด 1๋ก, 1์ด๋ฉด 0์ผ๋ก ๋ง๋ค๊ธฐ num = 0 print(num ^ 1) # 1
num1 = 7 # 0111 (2์ง๋ฒ) num2 = 8 # 1000 (2์ง๋ฒ) print(num1 ^ num2) # 15 (10์ง๋ฒ) == 1111 (2์ง๋ฒ)
-
-
Shift ์ฐ์ฐ
: bit๋ฅผ ํ์นธ์ฉ ๋ฐ๊ธฐ
num = 8 # 1000 (2์ง๋ฒ) print(num >> 1) # 4 (10์ง๋ฒ) == 0100 (2์ง๋ฒ) print(num >> 2) # 2 (10์ง๋ฒ) == 0010 (2์ง๋ฒ)
-
์ฐจ์งํฉ ๊ตฌํ๊ธฐ
- ์ฝ๋1. set์ผ๋ก ๋นผ๊ธฐ
lis1 = ['a', 'b', 'b', 'c'] lis2 = ['b', 'd'] result = set(lis1) - set(lis2) result = list(result) # ['a', 'c']
- ์ฝ๋2. set์
difference_update()์ด์ฉx = {"a", "b", "c"} y = {"d", "e", "a"} x.difference_update(y) print(x) # {'c', 'b'}
- ์ฝ๋1. set์ผ๋ก ๋นผ๊ธฐ
collections ๋ชจ๋
defaultdict- default ๊ฐ์ ์ค์ ํ์ฌ ๋์ ๋๋ฆฌ๋ฅผ ์์ฑ
- ์ด๋ค ์กฐ๊ฑด์ ๋ง์กฑํ๋ฉด ํน์ key์ value๋ฅผ ์ฆ๊ฐ์ํค๋ ๊ฒฝ์ฐ ์ ์ฉํ๊ฒ ์ฌ์ฉ
dic = collections.defaultdict(int) # default ๊ฐ : 0 dic['A'] += 1 # ์๋๋๋ก๋ผ๋ฉด ์กด์ฌํ์ง ์๋ key ๊ฐ์ด๋ฏ๋ก ์๋ฌ๊ฐ ๋ฐ์ํ์ง๋ง, {'A': 1}์ด ๋จ
Counter-
์์์ ๋น๋ ์ธ๊ธฐ
from collections import Counter lis = ['a', 'b', 'b', 'c', 'b'] # ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ Counter(lis) # Counter({'b': 3, 'a': 1, 'c': 1}) # List(Tuple) ํํ๋ก ์ ์ฒด ๋ฐํํ๊ธฐ Counter(lis).most_common() # [('b', 3), ('a', 1), ('c', 1)] # List(Tuple) ํํ๋ก ๋น๋ ์ ์์ k๊ฐ ๋ฐํํ๊ธฐ Counter(lis).most_common(2) # [('b', 3), ('a', 1)]
-
๋ ๋ฆฌ์คํธ ๋นผ๊ธฐ (์ฐจ์งํฉ)
- ์ฝ๋1) ์ค๋ณต ์์ ์ ๊ฑฐ
lis1 = ['a', 'b', 'b', 'c'] lis2 = ['b', 'd'] result = set(lis1) - set(lis2) result = list(result) # ['a', 'c']
- ์ฝ๋2) ์ค๋ณต ์์ ์ ์ง
from collections import Counter lis1 = ['a', 'b', 'b', 'c'] lis2 = ['b', 'd'] result = Counter(lis1) - Counter(lis2) # Counter({'a': 1, 'b': 1, 'c': 1})
- ์ฝ๋1) ์ค๋ณต ์์ ์ ๊ฑฐ
-
OrderedDict-
๋์ ๋๋ฆฌ์ ์ ๋ ฅ ์์๋ฅผ ์ ์ง
-
Python 3.7 ์ด์๋ถํฐ๋ ์๋์ผ๋ก ์ ๋ ฅ ์์๊ฐ ์ ์ง๋์ง๋ง, ํน์ ๋ชจ๋ฅผ ์ํฉ์ ์ํด ์ฌ์ฉํ์.
collections.OrderedDict({'c': 1, 'a': 5, 'b': 4}) # ๋์ ๋๋ฆฌ ํํ ์ ์ง
-
deque-
pop ์ฐ์ฐ์ ์์ฃผ ์ฌ์ฉํด์ผ ํ ๋, ๋ฆฌ์คํธ ๋์ deque๋ฅผ ์ด์ฉํ๋ฉด ์๋๋ฅผ ํจ์ฌ ๋์ผ ์ ์๋ค.
-
append(),popleft(),pop(),appendleft()์ฐ์ฐ์ ์๊ฐ๋ณต์ก๋๋ ๋ชจ๋ O(1)- ์ฐธ๊ณ : List์
pop(0)๋ O(n)
- ์ฐธ๊ณ : List์
-
rotate(k): k๊ฐ ์์์ด๋ฉด ์ค๋ฅธ์ชฝ์ผ๋ก k์นธ ํ์ , k๊ฐ ์์์ด๋ฉด ์ผ์ชฝ์ผ๋ก k์นธ ํ์ from collections import deque q = deque([1,3,5]) q.pop() # ๋งจ ๋ค ์์ pop q.popleft() # ๋งจ ์ ์์ pop, ๋ฆฌ์คํธ์ pop(0)๊ณผ ๋์ผํ ์ญํ q.append(10) # ๋งจ ๋ค์ ์์๋ฅผ ์ฝ์ q.appendleft(10) # ๋งจ ์์ ์์๋ฅผ ์ฝ์ q.rotate(1) # ์ค๋ฅธ์ชฝ์ผ๋ก ํ์นธ์ฉ ์ด๋ (ex: [1,3,5] -> [5,1,3]) q.rotate(-1) # ์ผ์ชฝ์ผ๋ก ํ์นธ์ฉ ์ด๋ (ex: [1,3,5] -> [3,5,1])
-
์์ ์ฐพ๊ธฐ
-
2๋ถํฐ ์ ๊ณฑ๊ทผ๊น์ง ๋๋์ด๋จ์ด์ง๋์ง ํ์ธํ๊ธฐ
# ๊ธฐ๋ณธ ์ฝ๋ def isPrime(num): for i in range(2, int(num**0.5) + 1): if num % i == 0: return False return True
# ๋ ํจ์จ์ ์ธ ์ฝ๋ def isPrime(num): if num % 2 == 0: return False for i in range(3, int(num**0.5) + 1, 2): if num % i == 0: return False return True
-
์๋ผํ ์คํ ๋ค์ค์ ์ฒด
: ์ฃผ์ด์ง ๋ฒ์์ ๊ฐ๋ค ์ค ์์๋ฅผ ๋ชจ๋ ์ฐพ์์ผํ ๋, 2๋ถํฐ์ ๋ฐฐ์๋ค์ ๋ชจ๋ ์ ์ธ์ํค๋ ๋ฐฉ๋ฒ
# 1๋ถํฐ 100๊น์ง์ ์ ์ค ์์๋ฅผ ์ถ๋ ฅํ์์ค. n = 100 primes = [True] * (n+1) # [0]๋ ์ฌ์ฉ์ํจ primes[1] = False # 1์ False ์ฒ๋ฆฌ for i in range(2, int(n**0.5)+1): # 2 ~ โn # i์ ๋ฐฐ์๋ค์ False ์ฒ๋ฆฌํ๊ธฐ (i ์์ ์ X) for idx in range(i*2, n+1, i): primes[idx] = False # ์์๋ค์ ์ถ๋ ฅ for idx in range(1, n+1): if primes[idx]: print(idx)
์ฝ์ ๊ตฌํ๊ธฐ
๋ฐฉ๋ฒ1: ํด๋น ๊ฐ(n)๊น์ง์ ๋ชจ๋ ๊ฐ์ ํ์ธํ๊ธฐ => ๋นํจ์จ์
๋ฐฉ๋ฒ2: โn๊น์ง์ ๋ชจ๋ ๊ฐ i๋ฅผ ํ์ธํ๋๋ฐ, ์ด ๋ ๋์๋๋ n//i ๊ฐ๋ ๋ฃ์ด์ค๋ค (์ ๊ณฑ์์ธ์ง ํ์ธํ๊ณ ๋ฃ๊ธฐ)
div_list = []
for i in range(1, int(n**0.5)+1):
if n % i == 0: # i๋ n์ ์ฝ์
div_list.append(i)
if n // i != i: # n//i๋ n์ ์ฝ์
div_list.append(n//i)
div_list = sorted(div_list) # ์ค๋ฆ์ฐจ์ ์ ๋ ฌ- +) ์ฝ์์ ๊ฐ์๊ฐ ํ์์ธ์ง ์ง์์ธ์ง ๊ตฌํ๊ธฐ
- ํด๋น ๊ฐ์ด ์ ๊ณฑ์์ด๋ฉด ์ฝ์์ ๊ฐ์๋ ํ์, ์ ๊ณฑ์๊ฐ ์๋๋ฉด ์ฝ์์ ๊ฐ์๋ ์ง์
- ์ ๊ณฑ์ ํ๋ณ :
if int(n**0.5) == n**0.5:
- ์ ๊ณฑ์ ํ๋ณ :
- ํด๋น ๊ฐ์ด ์ ๊ณฑ์์ด๋ฉด ์ฝ์์ ๊ฐ์๋ ํ์, ์ ๊ณฑ์๊ฐ ์๋๋ฉด ์ฝ์์ ๊ฐ์๋ ์ง์
์ด์ฐจ์ ๋ฐฐ์ด ํ์ ์ํค๊ธฐ
def rotate(arr): # arr๋ ์ด์ฐจ์ ๋ฐฐ์ด
row, col = len(arr), len(arr[0])
rotated_arr = [[0] * row for _ in range(col)]
for i in range(row):
for j in range(col):
rotated_arr[j][row-1-i] = arr[i][j] # ํต์ฌ!
return rotated_arrDFS / BFS
-
DFS
- ๊น๊ฒ ํ์
- ์ฌ๊ทํจ์ or Stack์ ์ด์ฉํด ๊ตฌํ
- ์๊ฐ๋ณต์ก๋: O(V+E)
- V๋ ๋ ธ๋ ์, E๋ ๊ฐ์ ์
# ์ฌ๊ทํจ์๋ก ๊ตฌํ def dfs(node): visited[node] = True print(node, end=' ') # ์ถ๋ ฅ for adj_node in graph[node]: if not visited[adj_node]: dfs(adj_node) n = 5 graph = [ [], # [0]์ ์ฌ์ฉํ์ง ์์ [2,3], [1,4,5], [1], [2,5], [2,4], ] visited = [False] * (n+1) # [0]์ ์ฌ์ฉํ์ง ์์ dfs(1) # ์์ ๋ ธ๋: 1 # ์ถ๋ ฅ ๊ฒฐ๊ณผ: 1 2 4 5 3
-
BFS
- ๋๊ฒ ํ์
- Queue๋ฅผ ์ด์ฉํด ๊ตฌํ
- ์๊ฐ๋ณต์ก๋: O(V+E)
- V๋ ๋ ธ๋ ์, E๋ ๊ฐ์ ์
- ์ต๋จ ๊ฒฝ๋ก ์ฐพ์ ๋ ์์ฃผ ์ฌ์ฉ
from collections import deque def bfs(start): q = deque() q.append(start) visited[start] = True while q: node = q.popleft() print(node, end=' ') # ์ถ๋ ฅ for adj_node in graph[node]: if not visited[adj_node]: q.append(adj_node) visited[adj_node] = True n = 5 graph = [ [], # [0]์ ์ฌ์ฉํ์ง ์์ [2,3], [1,4,5], [1], [2,5], [2,4], ] visited = [False] * (n+1) # [0]์ ์ฌ์ฉํ์ง ์์ bfs(1) # ์์ ๋ ธ๋: 1 # ์ถ๋ ฅ ๊ฒฐ๊ณผ: 1 2 3 4 5
- BFS์ ๋ค์ต์คํธ๋ผ์ ์ฐจ์ด์
- BFS์ ๋ค์ต์คํธ๋ผ ๋ชจ๋ ๊ทธ๋ํ์์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ฐพ๊ธฐ ์ํ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
- BFS์์๋ ๊ฐ์ ์ ์๋ฅผ ์ต์๋ก ํ๋ ๋ฐ๋ฉด, ๋ค์ต์คํธ๋ผ์์๋ ๊ฐ์ค์น์ ํฉ์ ์ต์๋ก ํ๋ค.
- ์ฆ, ๋์๊ฐ๋ ๊ฒฝ๋ก์ฌ๋ ๊ฐ์ค์น ํฉ์ด ์ต์์ด๊ธฐ๋ง ํ๋ฉด ๋๋ค๋ฉด ๋ค์ต์คํธ๋ผ๋ฅผ ์ฌ์ฉ
- BFS์์๋ ๊ฐ์ค์น๊ฐ ์๊ฑฐ๋ ๋์ผํ ๋ฐ๋ฉด, ๋ค์ต์คํธ๋ผ์์๋ ๊ฐ์ค์น๊ฐ ๋ค๋ฅผ ์ ์๋ค.
- BFS์์๋ Queue๋ฅผ ์ฌ์ฉํ๋ ๋ฐ๋ฉด, ๋ค์ต์คํธ๋ผ์์๋ Priority Queue ๋๋ Heap์ ์ฌ์ฉํ๋ค.
- ํ์ฌ ๋ ธ๋์ ์ธ์ ๋ ธ๋๋ค์ ํ์ํ ๋, BFS์์๋ ๋ฐฉ๋ฌธํ ์ ์ด ์๋์ง ํ์ธํ๋ ๋ฐ๋ฉด, ๋ค์ต์คํธ๋ผ์์๋ ์ต์ ๊ฑฐ๋ฆฌ์ธ์ง ํ์ธํ๋ค.
Queue
-
FIFO (First In First Out)
-
์ผ๋ฐ์ ์ผ๋ก
deque๋ฅผ ์ฌ์ฉํด ๊ตฌํ- ์ฝ์
:
append()(appendleft()๋ ์์) - ์ ๊ฑฐ:
popleft()(pop()๋ ์์)from collections import deque queue = deque() queue.append(3) queue.append(1) queue.popleft() # 3
- ์ฃผ์) ์์ ์ถ๊ฐ ์,
append()์ ๋ฆฌ์คํธ๋ฅผ ๋ฃ์ผ๋ฉด ๋ฆฌ์คํธ ์ ์ฒด๋ฅผ ํ๋์ ์์๋ก ์ถ๊ฐํ๋ฏ๋กextend()๋ฅผ ์ฌ์ฉqueue = deque() queue.append(0) queue.append([1,2,3]) # queue: deque([0,[1,2,3]]) queue = deque() queue.append(0) queue.extend([1,2,3]) # queue: deque([0,1,2,3])
- ์ฝ์
:
-
์ฐ์ ์์ ํ (Priority Queue)
: ๋จ์ํ ๋จผ์ ๋ค์ด์จ ๊ฐ์ ๋ฐํํ์ง ์๊ณ , ์ ์ฅ๋ ๊ฐ๋ค์ ์ ๋ ฌํด์ ๊ฐ์ฅ ์์ ๊ฐ์ ๋ฐํํจ
-
์ผ๋ฐ์ ์ผ๋ก
PriorityQueue๋ฅผ ์ฌ์ฉํด ๊ตฌํ- ์ฝ์
:
put() - ์ ๊ฑฐ:
get() - ์ค๋ฆ์ฐจ์ ๋ง๊ณ ๋ค๋ฅธ ๊ธฐ์ค์ผ๋ก ๋ฐํํ๊ณ ์ถ์ผ๋ฉด,
(์ฐ์ ์์, ๊ฐ)ํํ๋ก ์ ์ฅ- ex:
(1, 'lemon') - ์ฐ์ ์์๊ฐ ๋์ผํ ํํ๋ค์ ๊ฐ์ ๋ฐ๋ผ ์ ๋ ฌ๋จ
- ex:
- ์ฃผ์)
while queue:ํ๋ฉด ํญ์ True์ด๋ฏ๋กwhile queue.qsize() > 0:์ผ๋ก ์ฌ์ฉ
from queue import PriorityQueue queue = PriorityQueue() queue.put(3) queue.put(1) queue.put(5) print(queue.get()) # 1 print(queue.get()) # 3 print(queue.get()) # 5
from queue import PriorityQueue queue = PriorityQueue() queue.put((2, 'apple')) queue.put((1, 'lemon')) queue.put((1, 'blueberry')) print(queue.get()) # (1, 'blueberry') print(queue.get()) # (1, 'lemon') print(queue.get()) # (2, 'apple')
- ์ฝ์
:
-
heapq๋ก๋ ๊ตฌํ ๊ฐ๋ฅimport heapq heap = [] heapq.heappush(heap, 3) heapq.heappush(heap, 1) heapq.heappop(heap) # 1
import heapq heap = [3,5,1,4,2] heapq.heapify(heap) heapq.heappop(heap) # 1
-
Heap
-
์ต์๊ฐ/์ต๋๊ฐ์ ๋ฐ๋ณต์ ์ผ๋ก ์ฐพ์์ผํ ๋ ์ ์ฉํจ
-
Heap์ ์์ ์ด์งํธ๋ฆฌ์ด๋ฏ๋ก ๋์ด๊ฐ logn => ๋ชจ๋ ๋ ธ๋์ ๋ํด ์ฐ์ฐ์ ํด์ผํ๋ฏ๋ก ์๊ฐ๋ณต์ก๋๋ O(nlogn)
-
pop ์ฐ์ฐ์ ํ๋ฉด ๋ฃจํธ ๋ ธ๋์ ๊ฐ์ด ๋ฐํ๋จ (min heap์ด๋ฉด ์ต์๊ฐ, max heap์ด๋ฉด ์ต๋๊ฐ)
-
heapq๋ชจ๋์ min heap๋ง์ ์ง์ํจ- max heap์ ์ฌ์ฉํด์ผํ๋ค๋ฉด ์์๋ฅผ ๋ชจ๋ ์์๋ก ๋ง๋ค์ด์ ์ฌ์ฉํ๋ฉด ๋จ
import heapq # heap์ ๋ง๋ค๋ฉด์ ์์๋ฅผ ํ๋์ฉ ์ง์ด๋ฃ๊ธฐ heap = [] heapq.heappush(heap, 2) heapq.heappush(heap, 1) heapq.heappop(heap) # 1
import heapq # ๋ฆฌ์คํธ๋ฅผ ํ๋ฒ์ heap์ผ๋ก ๋ง๋ค๊ธฐ heap = [2, 1] heapq.heapify(heap) heapq.heappop(heap) # 1
-
heap์ ๋น์ฐ๋ ค๋ฉด
heap = []๋ก ๋ฆฌ์คํธ๋ฅผ ์ฌ์์ฑํด์ฃผ๋ฉด ๋จ
-
์ฃผ์)
heapify()์ ํจ๊ณผ- ๋ฆฌ์คํธ๊ฐ ์ ๋ ฌ๋จ (X)
- ํญ์ ์ต์๊ฐ์ root์ ๋ฐฐ์นํจ์ผ๋ก์จ
heappop()์ ํตํด ์ต์๊ฐ์ ์ป์ (O)
heap = [9,1,3,8] heapq.heapify(heap) # [1, 8, 3, 9] heapq.heappop(heap) # 1 heapq.heappop(heap) # 3 heapq.heappop(heap) # 8 heapq.heappop(heap) # 9 heap = [(9, 1), (1 ,2), (3, 4), (8, 7)] heapq.heapify(heap) # [(1, 2), (8, 7), (3, 4), (9, 1)] heapq.heappop(heap) # (1, 2) heapq.heappop(heap) # (3, 4) heapq.heappop(heap) # (8, 7) heapq.heappop(heap) # (9, 1)
-
Binary Search Tree์ ์ฑ์ง๊ณผ ํท๊ฐ๋ฆฌ์ง ๋ง ๊ฒ!
Tree
- Binary Tree
- ์์ ๋ ธ๋์ ์๋ ์ต๋ 2๊ฐ
- ์ผ๋ฐ์ ์ผ๋ก ๋ฆฌ์คํธ๋ก ๊ตฌํ
- root ๋ ธ๋์ index๋ 1
- index๋ก ๋
ธ๋๋ฅผ ์ด๋ํ๋ ๋ฐฉ๋ฒ
- ๋ฃจํธ ๋
ธ๋๋ก ์ด๋ =>
index = 1 - ๋ถ๋ชจ ๋
ธ๋๋ก ์ด๋ =>
index = index / 2 - ์ผ์ชฝ ์์ ๋
ธ๋๋ก ์ด๋ =>
index = index * 2 - ์ค๋ฅธ์ชฝ ์์ ๋
ธ๋๋ก ์ด๋ =>
index = index * 2 + 1
- ๋ฃจํธ ๋
ธ๋๋ก ์ด๋ =>
- ์๊ฐ๋ณต์ก๋: O(logn) (์ต์ ์ ๊ฒฝ์ฐ skewed tree์ด๋ฉด O(n))
-
Binary Search Tree
- ์์ ๋ ธ๋์ ์๋ ์ต๋ 2๊ฐ
- ์ด๋ค ๋ ธ๋์ ์ผ์ชฝ ์๋ธํธ๋ฆฌ๋ ํด๋น ๋ ธ๋ ๊ฐ๋ณด๋ค ์์ ๊ฐ์ ๊ฐ๋ ๋ ธ๋๋ค๋ก ์ด๋ฃจ์ด์ง
- ์ด๋ค ๋ ธ๋์ ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ๋ ํด๋น ๋ ธ๋ ๊ฐ๋ณด๋ค ํฐ ๊ฐ์ ๊ฐ๋ ๋ ธ๋๋ค๋ก ์ด๋ฃจ์ด์ง
์ด์ง ํ์ (Binary Search)
: start, mid, end๋ฅผ ์ฌ์ฉํ๋ฉด์, mid์ ๊ฐ์ด ์ฐพ๋ ๊ฐ๊ณผ ์ผ์นํ๋์ง ํ์ธ์ ๋ฐ๋ณตํ๋ ๋ฐฉ๋ฒ
- ์กฐ๊ฑด: ๋ฆฌ์คํธ๊ฐ ์ ๋ ฌ๋์ด ์์ด์ผํจ!
- ๊ฐ์ ๊ฐฏ์ or ๋ฒ์๊ฐ ์์ฒญ ํด ๋ ๋ง์ด ์ฌ์ฉ
- ์๊ฐ๋ณต์ก๋: O(logn)
- ์ฝ๋ฉํ ์คํธ ์์ฃผ ์ถ์
- ์ฝ๋1. ์ฌ๊ท๋ก ๊ตฌํ
arr = [8,4,0,2,6] arr.sort() # ์ ๋ ฌ ํ์! target = 4 def binary_search(start, end): if start > end: return -1 mid = (start + end) // 2 if arr[mid] == target: return mid elif arr[mid] > target: # end = mid - 1 binary_search(start, mid - 1) else: # start = mid + 1 binary_search(mid + 1, end) binary_search(0, len(arr)-1) # 2
- ์ฝ๋2. ๋ฐ๋ณต๋ฌธ์ผ๋ก ๊ตฌํ
arr = [8,4,0,2,6] arr.sort() # ์ ๋ ฌ ํ์! target = 4 def binary_search(start, end): while start <= end: mid = (start + end) // 2 if arr[mid] == target: return mid elif arr[mid] > target: end = mid - 1 else: start = mid + 1 return -1 # ํด๋น ๊ฐ์ด ์๋ ๊ฒฝ์ฐ binary_search(0, len(arr)-1) # 2
ํฌ ํฌ์ธํฐ
: start ํฌ์ธํฐ์ end ํฌ์ธํฐ๋ฅผ ์ค์ ํ๊ณ ๊ฐ์ ๋ฒ์๋ฅผ ๋ฐ์ ธ ํฌ์ธํฐ๋ฅผ ํ์นธ์ฉ ์ด๋์ํด
-
์๊ฐ๋ณต์ก๋: O(n)
-
์๊ฐ๋ณต์ก๋๊ฐ ๋ฎ๊ธฐ ๋๋ฌธ์, ์ฃผ๋ก ๊ฐ์ ๋ฒ์๊ฐ ํฌ๊ฑฐ๋ ๊ฐฏ์๊ฐ ๋ง์ ๋ ์ฌ์ฉํจ
-
์์ 1. k๋ฅผ ์ฐ์๋ ์๋ค์ ํฉ์ผ๋ก ๋ํ๋ผ ์ ์๋ ๊ฒฝ์ฐ์ ์
start, end = 1, 1 # ์์ฐ์์ฌ์ผํ๋ฏ๋ก 1๋ก ํ ๋น sum = 1 answer = 1 # k ํ๋๋ก๋ง ๊ตฌ์ฑ๋ ๊ฒฝ์ฐ๋ฅผ ํฌํจ while end < k: if sum < k: end += 1 sum += end elif sum == k: answer += 1 end += 1 sum += end else: start += 1 sum -= start print(answer)
-
์์ 2. k๋ฅผ ๋ ์์ ํฉ์ผ๋ก ๋ํ๋ผ ์ ์๋ ๊ฒฝ์ฐ์ ์
numbers = [2, 6, 4, 1, 5, 3] numbers.sort() # [1, 2, 3, 4, 5, 6] start, end = 0, len(numbers)-1 answer = 0 while start < end: if numbers[start] + numbers[end] > k: end -= 1 elif numbers[start] + numbers[end] == k: answer += 1 end -= 1 else: start += 1 print(answer)
์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ
-
๋ณํฉ(merge) ์ ๋ ฌ
: ๋ฆฌ์คํธ๋ฅผ ๋ ๊ฐ์ ๋ถ๋ถ์งํฉ์ผ๋ก ๋ฐ๋ณตํด ๋๋๊ณ , ์ด๋ฏธ ์ ๋ ฌ๋ ๋ถ๋ถ์งํฉ๋ค์ ๋ณํฉํ๋ฉฐ ์ ๋ ฌํ๋ ๋ฐฉ์
- ์ฌ๊ทํจ์๋ฅผ ํตํด ๋ฆฌ์คํธ๋ฅผ ์ชผ๊ฐ ํ, ํฌ ํฌ์ธํฐ๋ฅผ ์ด์ฉํด ๋ ๋ถ๋ถ์งํฉ์์ ์์ ๊ฐ๋ถํฐ ์ง์ด๋ฃ์
- ์๊ฐ๋ณต์ก๋: O(nlogn)
- ์ฝ๋ฉํ ์คํธ์์ ์์ฃผ ๋ฑ์ฅ
arr = [3,5,4,1,2] def merge_sort(arr): if len(arr) <= 1: return arr # ๋ฆฌ์คํธ ์ชผ๊ฐ๊ธฐ mid = len(arr) // 2 left_arr = merge_sort(arr[:mid]) right_arr = merge_sort(arr[mid:]) # ํฌ ํฌ์ธํฐ๋ฅผ ํ์ฉํด ์์ ๊ฐ๋ถํฐ ์ง์ด๋ฃ์ merged_arr = [] l, r = 0, 0 while l < len(left_arr) and r < len(right_arr): if left_arr[l] < right_arr[r]: merged_arr.append(left_arr[l]) l += 1 else: merged_arr.append(right_arr[r]) r += 1 # ๋จ์ ์์๋ค ์ฝ์ if l < len(left_arr): merged_arr += left_arr[l:] else: merged_arr += right_arr[r:] return merged_arr
-
๋ฒ๋ธ(bubble) ์ ๋ ฌ
: ์ธ์ ๊ฐ๋ผ๋ฆฌ ๋น๊ตํด์ swapํ๋ฉฐ ์ ๋ ฌํ๋ ๋ฐฉ์
- ์๊ฐ๋ณต์ก๋: O(n^2)
arr = [3,5,4,1,2] n = len(arr) for i in range(n-1): for j in range(n-1-i): if arr[j] > arr[j+1]: # swap arr[j], arr[j+1] = arr[j+1], arr[j]
-
์ฝ์ (insertion) ์ ๋ ฌ
: ํน์ ๊ฐ์ ์ด๋ฏธ ์ ๋ ฌ๋ ์์ญ์ ๊ฐ๋ค๊ณผ ํ๋์ฉ ๋น๊ตํด์ swapํ๋ฉด์ ์ ์ ํ ์์น์ ์ฝ์ ํ๋ ๋ฐฉ์
- i๋ index 1๋ถํฐ ์ค๋ฅธ์ชฝ์ผ๋ก, j๋ index i๋ถํฐ ์ผ์ชฝ์ผ๋ก ์ด๋.
- ์๊ฐ๋ณต์ก๋: O(n^2)
arr = [3,5,4,1,2] n = len(arr) for i in range(1, n): for j in range(i, 0, -1): if arr[j-1] > arr[j]: # swap arr[j-1], arr[j] = arr[j], arr[j-1] else: break
-
ํต(quick) ์ ๋ ฌ
: pivot์ ์ ์ ํด ํด๋น ๊ฐ์ ๊ธฐ์ค์ผ๋ก ๋์๋น๊ตํ๋ฉด์ ์ ๋ ฌํ๋ ๋ฐฉ์
- ์ฌ๊ทํจ์ ์ด์ฉ
- ์๊ฐ๋ณต์ก๋: O(nlogn) (๋ก ์๊ณ ์์ผ๋ฉด ๋๊ณ ์ต์ ์ ๊ฒฝ์ฐ O(n^2)์)
arr = [3,5,4,1,2] def quick_sort(arr): if len(arr) <= 1: return arr pivot = arr[0] # ์ฒซ๋ฒ์งธ ์์๋ฅผ pivot์ผ๋ก ์ค์ small_arr = [x for x in arr[1:] if x <= pivot] large_arr = [x for x in arr[1:] if x > pivot] return quick_sort(small_arr) + [pivot] + quick_sort(large_arr) print(quick_sort(arr)) # [1,2,3,4,5]
-
์ ํ(selection) ์ ๋ ฌ
: ๋จ์ ๋ถ๋ถ์์ ์ต์๊ฐ์ ์ฐพ๊ณ ๋จ์ ๋ถ๋ถ์ ๋งจ ์์ ์๋ ๋ฐ์ดํฐ์ swapํ๋ฉฐ ์ ๋ ฌํ๋ ๋ฐฉ์ (์ต๋๊ฐ๋ ๊ฐ๋ฅ)
- ์๊ฐ๋ณต์ก๋: O(n^2)
- ๊ตฌํ์ด ๋ณต์กํ๊ณ ์๊ฐ๋ณต์ก๋๋ ๋์ ์ฝํ ์์ ์ ์ฌ์ฉํ์ง ์์!
๊ทธ๋ฆฌ๋(Greedy) ์๊ณ ๋ฆฌ์ฆ
: ํ์ฌ ์ํ์์ ์ต์ ์ ์ ํ์ง๊ฐ ์ ์ฒด์์ ์ต์ ์ ์ ํ์ง๋ผ๊ณ ๊ฐ์ ํ๋ ์๊ณ ๋ฆฌ์ฆ
-
์ํ ๊ณผ์
- ํ์ฌ ์ํ์์ ์ต์ ์ ํด๋ฅผ ์ ํํ๋ค.
- ์ ํํ ํด๊ฐ ์ ์ฒด ๋ฌธ์ ์ ์ ์ฝ ์กฐ๊ฑด์ ๋ฒ์ด๋์ง ์๋์ง ํ์ธํ๋ค.
- ํ์ฌ๊น์ง ์ ํํ ํด์ ์งํฉ์ด ์ ์ฒด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋์ง ํ์ธํ๋ค.
ํด๊ฒฐํ์ง ๋ชปํ๋ค๋ฉด 1๋ฒ์ผ๋ก ๋์๊ฐ ๋ฐ๋ณตํ๋ค.
-
๋ํ ๋ฌธ์ : ์ต์ ๊ฐฏ์์ ๋์ ์ ์ฌ์ฉํด ์ฃผ์ด์ง ๊ธ์ก ๋ง๋ค๊ธฐ
์ ๋์จ ํ์ธ๋ (union-find)
-
union(a, b)
- a ๋ ธ๋์ ๋ํ ๋ ธ๋์ b ๋ ธ๋์ ๋ํ ๋ ธ๋ ์ค, ๋ ํฐ ๋ํ ๋ ธ๋๋ฅผ ๋ ์์ ๋ํ ๋ ธ๋์ ์ฐ๊ฒฐ์ํด
-
find(a)
- a ๋ ธ๋์ ๋ํ ๋ ธ๋๋ฅผ ๋ฐํ
- ์ฌ๊ท๋ฅผ ํตํด์ ๋ํ ๋ ธ๋๋ฅผ ์ฐพ์
- ๋ํ ๋ ธ๋๋ฅผ ์ฐพ์ ํ, ์ฌ๊ท๋ฅผ ๋น ์ ธ๋์ค๋ฉด์ ๊ฑฐ์น๋ ๋ชจ๋ ๋ ธ๋์ ๋ํ ๋ ธ๋๋ฅผ ์ ๋ฐ์ดํธํจ => ๊ทธ๋ํ๋ฅผ ์ ๋ํ๊ณ ์๊ฐ ๋ณต์ก๋๋ฅผ ์ค์ด๋ ์ญํ ์ ํจ
-
๊ตฌํ ์ฝ๋
parents = list(range(n + 1)) # ๊ฐ ๋ ธ๋์ ๋ํ ๋ ธ๋๋ฅผ ์๋ฏธ def find(a): if a == parents[a]: # ๋ํ๋ ธ๋ return a else: parent_a = find(parents[a]) parents[a] = parent_a # ๋ํ๋ ธ๋ ์ ๋ฐ์ดํธ return parent_a def union(a, b): parent_a = find(a) parent_b = find(b) if parent_a <= parent_b: parents[parent_b] = parent_a else: parents[parent_a] = parent_b # ์๋์ฒ๋ผ ์์ฑํ์ง ์๊ฒ ์ฃผ์!! ๋ํ๋ ธ๋๋ผ๋ฆฌ ์ฐ๊ฒฐ์ ํด์ผํจ # if a <= b: # parents[b] = parent_a # else: # parents[a] = parent_b
-
์์ฃผ ์ค์ํ๋ ๋ถ๋ถ
- find ์ฐ์ฐ์์, ์ฌ๊ท๋ฅผ ๋น ์ ธ๋์ค๋ฉด์ ๋ชจ๋ ๋ ธ๋์ ๋ํ ๋ ธ๋๋ฅผ ๊ผญ ์ ๋ฐ์ดํธํด์ผ ํจ
- union ์ฐ์ฐ์์, a์ b ๋ ธ๋๋ผ๋ฆฌ ์ฐ๊ฒฐํ๋ ๊ฒ ์๋๋ผ a์ b์ ๋ํ๋ ธ๋๋ผ๋ฆฌ ์ฐ๊ฒฐํด์ผ ํจ
์์ ์ ๋ ฌ
: ์ฌ์ดํด์ด ์๋ ๋ฐฉํฅ ๊ทธ๋ํ์์ ๋ ธ๋์ ์์๋ฅผ ์ฐพ๋ ์๊ณ ๋ฆฌ์ฆ
-
์ ๋ ฌ ๊ฒฐ๊ณผ๊ฐ ์ ์ผํ์ง๋ ์์
-
์๊ฐ๋ณต์ก๋: O(V+E)
-
๊ตฌํ ๋ฐฉ๋ฒ
- ๊ทธ๋ํ์ ๋ณ๊ฐ๋ก, ์๊ธฐ ์์ ์ ๊ฐ๋ฆฌํค๋ ๊ฐ์ ์ ์๋ฅผ ์๋ฏธํ๋ ์ง์ ์ฐจ์(in-degree) ๋ฆฌ์คํธ๋ฅผ ๋ง๋ฆ
- ์ง์ ์ฐจ์๊ฐ 0์ธ ๋ ธ๋๋ค์ queue์ ์ฝ์
- queue์์ ๋
ธ๋๋ฅผ ๋ฝ๊ณ (๊ฒฐ๊ณผ๊ฐ์ ์ ์ฅ)
ํด๋น ๋ ธ๋๊ฐ ๊ฐ๋ฆฌํค๋ ๋ ธ๋๋ค์ ์ง์ ์ฐจ์๋ฅผ 1 ๊ฐ์์ํด
๊ฐ์ ํ ์ง์ ์ฐจ์๊ฐ 0์ด ๋ ๋ ธ๋๋ค์ queue์ ์ฝ์ - queue๊ฐ ๋น ๋๊น์ง 3๋ฒ ์์ ์ ๋ฐ๋ณต
from collections import deque n = 5 graph = [ [], [2,3], # node 1 [4,5], # node 2 [4], # node 3 [5], # node 4 [], # node 5 ] # 1๋ฒ ์์ indegree = [0, 0, 1, 1, 2, 2] # 2๋ฒ ์์ queue = deque() for i in range(1, n+1): if indegree[i] == 0: queue.append(i) while queue: # 3๋ฒ ์์ node = queue.popleft() print(node, end=' ') # ๊ฒฐ๊ณผ ๊ฐ ์ถ๋ ฅ for next_node in graph[node]: indegree[next_node] -= 1 if indegree[next_node] == 0: queue.append(next_node)
๋ค์ต์คํธ๋ผ (Dijkstra) ์๊ณ ๋ฆฌ์ฆ
: ํน์ ๋ ธ๋์์ ๋ค๋ฅธ ๋ชจ๋ ๋ ธ๋๋ค๊น์ง์ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ ๋ ์ฌ์ฉ
-
ํน์ง
- ๋ ธ๋ ๊ฐ ๊ฑฐ๋ฆฌ๊ฐ ์ฃผ์ด์ง๋ ๋ฐฉํฅ ๊ทธ๋ํ์ฌ์ผ ํจ
- ๊ฑฐ๋ฆฌ๋ ๋ชจ๋ ์์์ฌ์ผ ํจ
- ๊ฐ์ค์น์ ํฉ์ด ์ต์๊ฐ ๋๋ ๊ฒฝ๋ก๋ฅผ ์ฐพ์
-
์๊ฐ๋ณต์ก๋: O(ElogV)
-
๊ตฌํ ๋ฐฉ๋ฒ
- (๋ ธ๋, ๊ฑฐ๋ฆฌ)๋ฅผ ์ธ์ ๋ฆฌ์คํธ์ ์ ์ฅํด ๊ทธ๋ํ๋ฅผ ๋ง๋ ๋ค.
distance๋ฆฌ์คํธ๋ฅผ ๋ง๋ค๊ณ , ์ถ๋ฐ ๋ ธ๋์ ๊ฑฐ๋ฆฌ๋ 0, ๋ค๋ฅธ ๋ ธ๋๋ค์ ๊ฑฐ๋ฆฌ๋ INF๋ก ์ด๊ธฐํํ๋ค.- ๊ฑฐ๋ฆฌ๊ฐ ๊ฐ์ฅ ์์ ๋
ธ๋๋ฅผ ์ ํํ๋ค.
- ์ด๋ฅผ ์ํด ์ฐ์ ์์ ํ๋ฅผ ์ฌ์ฉํด์ผ ํจ (
PriorityQueue/heapq) - ํ์ (๊ฑฐ๋ฆฌ, ๋ ธ๋) ์์ผ๋ก ์ ์ฅํด์ผ ํจ
- ์ด๋ฅผ ์ํด ์ฐ์ ์์ ํ๋ฅผ ์ฌ์ฉํด์ผ ํจ (
- ์ ํํ ๋
ธ๋์ ์ฐ๊ฒฐ๋ ๋
ธ๋๋ค์ ๋ํด ๊ฑฐ๋ฆฌ๋ฅผ ์
๋ฐ์ดํธํ๋ค.
distance[adj_node]๊ณผdist + adj_dist์ค ๋ ์์ ๊ฒ
- ๋ชจ๋ ๋ ธ๋๊ฐ ์ ํ๋ ๋๊น์ง 3~4๋ฒ์ ๋ฐ๋ณตํ๋ค.
-
์ฝ๋1:
heapq๋ก ๊ตฌํimport heapq graph = [[] for _ in range(n + 1)] for _ in range(d): src_node, tgt_node, dist = map(int, input().split()) graph[src_node].append((tgt_node, dist)) INF = 10 ** 5 distance = [INF] * (n + 1) # priority queue ๋ง๋ค๊ธฐ queue = [] heapq.heappush(queue, (0, start)) # (๊ฑฐ๋ฆฌ, ๋ ธ๋) ์์ผ๋ก ์ ์ฅ distance[start] = 0 # ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ while queue: dist, node = heapq.heappop(queue) # ๊ฐ์ฅ ๊ฑฐ๋ฆฌ๊ฐ ์์ ๋ ธ๋ ๋ฐํ if dist > distance[node]: # invalid continue for adj_node, adj_dist in graph[node]: if dist + adj_dist < distance[adj_node]: # ์ต๋จ ๊ฑฐ๋ฆฌ ์ ๋ฐ์ดํธ # if distance[node] + adj_dist < distance[adj_node]: # ์ด๋ ๊ฒ ์์ฑํ์ง ์๋๋ก ์ฃผ์! distance[adj_node] = dist + adj_dist heapq.heappush(queue, (distance[adj_node], adj_node)) # (๊ฑฐ๋ฆฌ, ๋ ธ๋) ์์ผ๋ก ์ ์ฅ
-
์ฝ๋2:
PriorityQueue๋ก ๊ตฌํfrom queue import PriorityQueue graph = [[] for _ in range(n + 1)] for _ in range(d): src_node, tgt_node, dist = map(int, input().split()) graph[src_node].append((tgt_node, dist)) INF = 10 ** 5 distance = [INF] * (n + 1) # priority queue ๋ง๋ค๊ธฐ queue = PriorityQueue() queue.put((0, start)) # (๊ฑฐ๋ฆฌ, ๋ ธ๋) ์์ผ๋ก ์ ์ฅ distance[start] = 0 # ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ while queue.qsize() > 0: dist, node = queue.get() # ๊ฐ์ฅ ๊ฑฐ๋ฆฌ๊ฐ ์์ ๋ ธ๋ ๋ฐํ if dist > distance[node]: # invalid continue for adj_node, adj_dist in graph[node]: if dist + adj_dist < distance[adj_node]: # ์ต๋จ ๊ฑฐ๋ฆฌ ์ ๋ฐ์ดํธ distance[adj_node] = dist + adj_dist queue.put((distance[adj_node], adj_node)) # (๊ฑฐ๋ฆฌ, ๋ ธ๋) ์์ผ๋ก ์ ์ฅ
- BFS์ ๋ค์ต์คํธ๋ผ์ ์ฐจ์ด์
- BFS์ ๋ค์ต์คํธ๋ผ ๋ชจ๋ ๊ทธ๋ํ์์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ฐพ๊ธฐ ์ํ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
- BFS์์๋ ๊ฐ์ ์ ์๋ฅผ ์ต์๋ก ํ๋ ๋ฐ๋ฉด, ๋ค์ต์คํธ๋ผ์์๋ ๊ฐ์ค์น์ ํฉ์ ์ต์๋ก ํ๋ค.
- ์ฆ, ๋์๊ฐ๋ ๊ฒฝ๋ก์ฌ๋ ๊ฐ์ค์น ํฉ์ด ์ต์์ด๊ธฐ๋ง ํ๋ฉด ๋๋ค๋ฉด ๋ค์ต์คํธ๋ผ๋ฅผ ์ฌ์ฉ
- BFS์์๋ ๊ฐ์ค์น๊ฐ ์๊ฑฐ๋ ๋์ผํ ๋ฐ๋ฉด, ๋ค์ต์คํธ๋ผ์์๋ ๊ฐ์ค์น๊ฐ ๋ค๋ฅผ ์ ์๋ค.
- BFS์์๋ Queue๋ฅผ ์ฌ์ฉํ๋ ๋ฐ๋ฉด, ๋ค์ต์คํธ๋ผ์์๋ Priority Queue ๋๋ Heap์ ์ฌ์ฉํ๋ค.
- ํ์ฌ ๋ ธ๋์ ์ธ์ ๋ ธ๋๋ค์ ํ์ํ ๋, BFS์์๋ ๋ฐฉ๋ฌธํ ์ ์ด ์๋์ง ํ์ธํ๋ ๋ฐ๋ฉด, ๋ค์ต์คํธ๋ผ์์๋ ์ต์ ๊ฑฐ๋ฆฌ์ธ์ง ํ์ธํ๋ค.
๋ฒจ๋ง-ํฌ๋ (Bellman-ford) ์๊ณ ๋ฆฌ์ฆ
: ํน์ ๋ ธ๋์์ ๋ค๋ฅธ ๋ชจ๋ ๋ ธ๋๋ค๊น์ง์ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ ๋ ์ฌ์ฉ (์์ ๊ฑฐ๋ฆฌ๊ฐ ์์ ๋!)
-
ํน์ง
- ๋ ธ๋ ๊ฐ ๊ฑฐ๋ฆฌ๊ฐ ์ฃผ์ด์ง๋ ๋ฐฉํฅ ๊ทธ๋ํ์ฌ์ผ ํจ
- ๊ฑฐ๋ฆฌ๊ฐ ์์์ฌ๋ ๋จ
- ๋ ธ๋๊ฐ n๊ฐ์ผ ๋ ์ฃ์ง์ ์ต๋ ๊ฐฏ์๋ (n-1)์ด๋ฏ๋ก ๊ฑฐ๋ฆฌ ์ ๋ฐ์ดํธ๋ฅผ (n-1)๋ฒ ๋ฐ๋ณต
-
์๊ฐ๋ณต์ก๋: O(VE)
-
์ฝ๋ฉํ ์คํธ์์๋ ์ต๋จ ๊ฑฐ๋ฆฌ ๊ตฌํ๋ ๋ฌธ์ ๋ณด๋ค ์์ ์ฌ์ดํด์ ํ๋ณํ๋ ๋ฌธ์ ๊ฐ ๋ ๋ง์ด ์ถ์ ๋จ
-
๊ตฌํ ๋ฐฉ๋ฒ
- ๊ทธ๋ํ๋ฅผ ์ฃ์ง ๋ฆฌ์คํธ๋ก ๊ตฌํํ๋ค.
- ์ฃ์ง ๋ฆฌ์คํธ์ ๊ฐ ์ธ๋ฑ์ค๋ง๋ค (๋ ธ๋1, ๋ ธ๋2, ๊ฐ์ค์น)๊ฐ ์ ์ฅ๋จ
distance๋ฆฌ์คํธ๋ฅผ ๋ง๋ค๊ณ , ์ถ๋ฐ ๋ ธ๋์ ๊ฑฐ๋ฆฌ๋ 0, ๋ค๋ฅธ ๋ ธ๋๋ค์ ๊ฑฐ๋ฆฌ๋ INF๋ก ์ด๊ธฐํํ๋ค.- ๊ฑฐ๋ฆฌ ์
๋ฐ์ดํธ๋ฅผ (n-1)๋ฒ ๋ฐ๋ณตํ๋ค.
distance[src_node] == INF์ผ ๋, ๊ฐ์ ์ ๋ฐ์ดํธํ์ง Xdistance[src_node] + weight < distance[tgt_node]์ผ ๋,distance[tgt_node]๋ฅผ ์ ๋ฐ์ดํธ
- ์์ ์ฌ์ดํด์ด ์กด์ฌํ๋์ง ํ์ธํ๋ค.
- ๋ชจ๋ ์ฃ์ง๋ฅผ ํ๋ฒ์ฉ ๋ค์ ์ฌ์ฉํด ์ ๋ฐ์ดํธ๋ ๋ ธ๋๊ฐ ์๋์ง ํ์ธ
- ์ ๋ฐ์ดํธ๊ฐ ์ผ์ด๋ฌ์ผ๋ฉด ์์ ์ฌ์ดํด์ด ์กด์ฌํ๋ ๊ฒ => ์ต๋จ ๊ฑฐ๋ฆฌ ์ฐพ์ ์ ์์
# ๊ทธ๋ํ๋ฅผ ์ฃ์ง ๋ฆฌ์คํธ๋ก ๊ตฌํ graph = [] for _ in range(m): src_node, tgt_node, dist = map(int, input().split()) graph.append((src_node, tgt_node, dist)) # distance ๋ฆฌ์คํธ ๋ง๋ค๊ธฐ INF = 10 ** 6 distance = [INF] * (n+1) # start ๋ ธ๋ start = 1 distance[start] = 0 # ๋ฒจ๋ง-ํฌ๋ ์๊ณ ๋ฆฌ์ฆ for _ in range(n-1): # (n-1)๋ฒ ๋ฐ๋ณต for (src_node, tgt_node, dist) in graph: if distance[src_node] != INF and distance[src_node] + dist < distance[tgt_node]: distance[tgt_node] = distance[src_node] + dist # ์์ ์ฌ์ดํด ํ๋ณ neg_cycle = False for (src_node, tgt_node, dist) in graph: # 1๋ฒ ๋ฐ๋ณต if distance[src_node] != INF and distance[src_node] + dist < distance[tgt_node]: # ์ ๋ฐ์ดํธ๊ฐ ์ผ์ด๋๋ ๊ฒฝ์ฐ (์์ ์ฌ์ดํด ์กด์ฌ) neg_cycle = True break
- ๊ทธ๋ํ๋ฅผ ์ฃ์ง ๋ฆฌ์คํธ๋ก ๊ตฌํํ๋ค.
ํ๋ก์ด๋-์์ (Floyd-warshall) ์๊ณ ๋ฆฌ์ฆ
: ๋ชจ๋ ๋ ธ๋ ๊ฐ์ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ ๋ ์ฌ์ฉ
-
ํน์ง
- ๋ ธ๋ ๊ฐ ๊ฑฐ๋ฆฌ๊ฐ ์ฃผ์ด์ง๋ ๋ฐฉํฅ ๊ทธ๋ํ์ฌ์ผ ํจ
- ๊ฑฐ๋ฆฌ๊ฐ ์์์ฌ๋ ๋จ
- Dynamic Programming์ ์๋ฆฌ๋ฅผ ์ด์ฉ
- A โ B ๋ก ๊ฐ๋ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ๊ตฌํ์ ๋, ๊ทธ ๊ฒฝ๋ก ์์ ์กด์ฌํ๋ C ๋ ธ๋์ ๋ํด A โ C, C โ B ๊ฒฝ๋ก ์ญ์ ์ต๋จ ๊ฒฝ๋ก์
-
์๊ฐ๋ณต์ก๋: O(V^3)
- ์๊ฐ๋ณต์ก๋๊ฐ ๋๊ธฐ ๋๋ฌธ์ ๋ ธ๋ ์๋ ์ ๊ฒ ์ฃผ์ด์ง
-
๊ตฌํ ๋ฐฉ๋ฒ
distance๋ฆฌ์คํธ๋ฅผ ์ด์ฐจ์์ผ๋ก ๋ง๋ค๊ณ , ์๊ธฐ ์์ ์ ๋ปํ๋ ๋๊ฐ์ ์นธ์ ๊ฑฐ๋ฆฌ๋ 0, ๋ค๋ฅธ ์นธ์ ๊ฑฐ๋ฆฌ๋ INF๋ก ์ด๊ธฐํํ๋ค.- ๊ทธ๋ํ์ ๋ฐ์ดํฐ๋ฅผ
distance๋ฆฌ์คํธ์ ์ ์ฅํ๋ค. - 3์ค for๋ฌธ์ผ๋ก ์ ํ์์ ๋ฐ๋ผ ๊ฑฐ๋ฆฌ๋ฅผ ์
๋ฐ์ดํธํ๋ค.
- for๋ฌธ ์์: ๊ฒฝ์ ๋ ธ๋ K์ ๋ํด โ ์ถ๋ฐ ๋ ธ๋ S์ ๋ํด โ ๋์ฐฉ ๋ ธ๋ E์ ๋ํด
- ์ ํ์:
distance[S][E] = min(distance[S][E], distance[S][K] + distance[K][E])
# distance ๋ฆฌ์คํธ ๋ง๋ค๊ธฐ INF = 10 ** 6 distance = [[INF] * (n+1) for _ in range(n+1)] for i in range(1, n+1): distance[i][i] = 0 # ๊ทธ๋ํ์ ๋ฐ์ดํฐ๋ฅผ distance ๋ฆฌ์คํธ์ ์ ์ฅํ๊ธฐ for _ in range(m): s, e, dist = map(int, input().split()) if distance[s][e] > dist: distance[s][e] = dist # ํ๋ก์ด๋-์์ ์๊ณ ๋ฆฌ์ฆ # 3์ค for๋ฌธ์ผ๋ก ๊ฑฐ๋ฆฌ ์ ๋ฐ์ดํธ for k in range(1, n+1): for i in range(1, n+1): for j in range(1, n+1): if distance[i][j] > distance[i][k] + distance[k][j]: # ์ ํ์ distance[i][j] = distance[i][k] + distance[k][j]
์ต์ ์ ์ฅ ํธ๋ฆฌ (minimum spanning tree)
: ๊ทธ๋ํ์์ ๋ชจ๋ ๋ ธ๋๋ฅผ ์ฐ๊ฒฐํ ๋ ์ฌ์ฉ๋ ์์ง๋ค์ ๊ฐ์ค์น ํฉ์ ์ต์๋ก ํ๋ ํธ๋ฆฌ
-
ํน์ง
- ์ฌ์ดํด์ด ์๊ธฐ์ง ์๋๋ก ์ฐ๊ฒฐํจ
- ๋ ธ๋๊ฐ n๊ฐ์ด๋ฉด ์ต์ ์ ์ฅ ํธ๋ฆฌ๋ฅผ ๊ตฌ์ฑํ๋ ์์ง๋ ํญ์ (n-1)๊ฐ
- ์ ๋์จ ํ์ธ๋๋ฅผ ํ์ฉํด ๊ตฌํ
-
๊ตฌํ ๋ฐฉ๋ฒ
- ๊ทธ๋ํ๋ฅผ ์ฃ์ง ๋ฆฌ์คํธ๋ก ๊ตฌํํ๋ค. ์ ๋์จ ํ์ธ๋ ๋ฆฌ์คํธ๋ ์ด๊ธฐํํ๋ค.
- ์ฃ์ง ๋ฆฌ์คํธ์ ๊ฐ ์ธ๋ฑ์ค๋ง๋ค (๋ ธ๋1, ๋ ธ๋2, ๊ฐ์ค์น)๊ฐ ์ ์ฅ๋จ
- ์ฃ์ง ๋ฆฌ์คํธ๋ฅผ ๊ฐ์ค์น ๊ธฐ์ค์ผ๋ก ์ ๋ ฌํ๋ค.
- ์ด๋ฅผ ์ํด ์ฃ์ง ๋ฆฌ์คํธ๋ฅผ ์ฐ์ ์์ ํ๋ก ๊ตฌํ
- ๊ฐ์ค์น๊ฐ ๋ฎ์ ์ฃ์ง๋ถํฐ ์์๋๋ก ์ ํํด, ์ฌ์ดํด์ด ํ์ฑ๋์ง ์๋์ง ํ์ธ ํ ๋ ๋
ธ๋๋ฅผ ์ฐ๊ฒฐํ๋ค.
- ์ฌ์ดํด ํ์ฑ ํ์ธ: find ์ฐ์ฐ
- ๋ ๋ ธ๋๋ฅผ ์ฐ๊ฒฐ: union ์ฐ์ฐ
- ์ฐ๊ฒฐ๋ ์ฃ์ง๊ฐ (n-1)๊ฐ๊ฐ ๋ ๋๊น์ง 3๋ฒ ์์ ์ ๋ฐ๋ณตํ๋ค.
from queue import PriorityQueue import sys input = sys.stdin.readline V, E = map(int, input().split()) queue = PriorityQueue() for _ in range(E): node1, node2, weight = map(int, input().split()) queue.put((weight, node1, node2)) # weight ๊ธฐ์ค์ผ๋ก ์ ๋ ฌ parents = list(range(V + 1)) def find(node): if node == parents[node]: return node else: parent_node = find(parents[node]) parents[node] = parent_node return parent_node def union(node1, node2): node1_parent = find(node1) node2_parent = find(node2) if node1_parent <= node2_parent: parents[node2_parent] = node1_parent else: parents[node1_parent] = node2_parent weight_sum, edge_cnt = 0, 0 while queue.qsize() > 0 and edge_cnt < V-1: weight, node1, node2 = queue.get() # ์ฌ์ดํด ํ์ฑ ์ฌ๋ถ ํ์ธ node1_parent, node2_parent = find(node1), find(node2) if node1_parent == node2_parent: # ์ฐ๊ฒฐ X continue # ๋ ๋ ธ๋ ์ฐ๊ฒฐ union(node1, node2) weight_sum += weight edge_cnt += 1 print(weight_sum)
- ๊ทธ๋ํ๋ฅผ ์ฃ์ง ๋ฆฌ์คํธ๋ก ๊ตฌํํ๋ค. ์ ๋์จ ํ์ธ๋ ๋ฆฌ์คํธ๋ ์ด๊ธฐํํ๋ค.
์ธ๊ทธ๋จผํธ ํธ๋ฆฌ (Segment Tree)
: ๋ฐ์ดํฐ์ ํน์ ๊ตฌ๊ฐ ํฉ๊ณผ ์ ๋ฐ์ดํธ๋ฅผ ๋น ๋ฅด๊ฒ ์ํํ๊ธฐ ์ํด ์ฌ์ฉ
-
์ธ๊ทธ๋จผํธ ํธ๋ฆฌ์ ์ข ๋ฅ: ๊ตฌ๊ฐ ํฉ, ์ต๋๊ฐ, ์ต์๊ฐ
-
์ธ๊ทธ๋จผํธ ํธ๋ฆฌ ๋ง๋ค๊ธฐ
- ๋ฐ์ดํฐ๊ฐ
$N$ ๊ฐ์ผ ๋,$2^k >= N$ ์ ๋ง์กฑํ๋ ์ต์์$k$ ๋ฅผ ๊ตฌํ ํ,$2^{k+1}$ ํฌ๊ธฐ์ ํธ๋ฆฌ ๋ฆฌ์คํธ๋ฅผ ๋ง๋ฆ - ํธ๋ฆฌ ๋ฆฌ์คํธ์
$2^k$ index๋ถํฐ ์ฃผ์ด์ง ๋ฐ์ดํฐ$N$ ๊ฐ๋ฅผ ์ฑ์ (Leaf ๋ ธ๋) - ์ฑ์์ง ๊ฐ์ ์ด์ฉํด ๋ถ๋ชจ ๋
ธ๋๋ก ์ฌ๋ผ๊ฐ๋ฉด์ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ์ ์ข
๋ฅ์ ๋ฐ๋ผ ๊ฐ์ ์ฑ์
- ๊ตฌ๊ฐ ํฉ: tree[i] = tree[2i] + tree[2i+1]
- ์ต๋๊ฐ: tree[i] = max(tree[2i], tree[2i+1])
- ์ต์๊ฐ: tree[i] = min(tree[2i], tree[2i+1])
- ๋ฐ์ดํฐ๊ฐ
-
๊ตฌ๊ฐ ํฉ/์ต๋๊ฐ/์ต์๊ฐ ๊ตฌํ๊ธฐ
- ์ฃผ์ด์ง ์ง์ index๋ฅผ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ์ Leaf ๋
ธ๋์ ํด๋นํ๋ index๋ก ๋ณ๊ฒฝ
- ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ index = ์ง์ index + (
$2^k - 1$ )
- ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ index = ์ง์ index + (
- ๋ค์์ ๊ณผ์ ์ ๊ฑฐ์นจ
-
start_index % 2 == 1์ด๋ฉด ํด๋น ๋ ธ๋๋ฅผ ์ ํํด ์ฐ์ฐ ์ํstart_index += 1
-
end_index % 2 == 0์ด๋ฉด ํด๋น ๋ ธ๋๋ฅผ ์ ํํด ์ฐ์ฐ ์ํend_index -= 1
- start_index์ depth ๋ณ๊ฒฝ:
start_index = start_index // 2 - end_index์ depth ๋ณ๊ฒฝ:
end_index = end_index // 2
- a~d ์์
์ ๋ฐ๋ณตํ๋ค๊ฐ
start_index > end_index๊ฐ ๋๋ฉด ์ข ๋ฃ
-
- ์ฃผ์ด์ง ์ง์ index๋ฅผ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ์ Leaf ๋
ธ๋์ ํด๋นํ๋ index๋ก ๋ณ๊ฒฝ
-
๊ฐ ์ ๋ฐ์ดํธํ๊ธฐ
- ์ ๋ฐ์ดํธ๋ ๋ ธ๋์ ๊ฐ๊ณผ ๋ถ๋ชจ๊ฐ ๊ฐ์ ๋ค๋ฅธ ์์ ๋ ธ๋์ ๊ฐ์ ๋ํด ์ฐ์ฐํ๊ณ ๊ณ์ํด์ ๋ถ๋ชจ ๋ ธ๋๋ก ์ฌ๋ผ๊ฐ
- ์ ๋ฐ์ดํธ๊ฐ ์ผ์ด๋์ง ์์ผ๋ฉด ์ข ๋ฃ
- ex) ์ต๋๊ฐ ํธ๋ฆฌ์์, 6๋ฒ ๋ ธ๋์ ๊ฐ์ด ์ ๋ฐ์ดํธ๋จ โ 6๋ฒ๊ณผ 7๋ฒ ๋ ธ๋์ ๊ฐ ์ค ๋ ํฐ ๊ฐ์ ๋ถ๋ชจ์ธ 3๋ฒ ๋ ธ๋์ ์ ๋ฐ์ดํธ โ 3๋ฒ ๋ ธ๋์ 2๋ฒ ๋ ธ๋ ๊ฐ ๋น๊ตํด์ ๋ ํฐ ๊ฐ์ ๋ถ๋ชจ์ธ 1๋ฒ ๋ ธ๋์ ์ ๋ฐ์ดํธ
-
์ฝ๋
# 2^k>=N ๋ง์กฑํ๋ k ๊ตฌํ๊ธฐ length = N k = 0 while length != 0: length = length // 2 k += 1 # N: 5, k = 0 # N: 2, k = 1 # N: 1, k = 2 # N: 0, k = 3 # 2^(k+1) ํฌ๊ธฐ์ ๋ฆฌ์คํธ ๋ง๋ค๊ธฐ # ์ต์๊ฐ ํธ๋ฆฌ์์๋ INF๋ก ์ด๊ธฐํ, ๊ตฌ๊ฐํฉ/์ต๋๊ฐ ํธ๋ฆฌ์์๋ 0์ผ๋ก ์ด๊ธฐํ INF = 10 ** 6 tree_size = 2 ** (k+1) tree = [INF] * (tree_size + 1) # [0]์ ์ฌ์ฉ X # 2^k index๋ถํฐ ์ฃผ์ด์ง ๋ฐ์ดํฐ ์ ์ฅ for i in range(2**k, 2**k + N): tree[i] = int(input()) # ๋ฐ์ดํฐ ์ ๋ ฅ # ๋ถ๋ชจ ๋ ธ๋๋ก ์ฌ๋ผ๊ฐ๋ฉด์ ๊ฐ ์ฑ์ฐ๊ธฐ i = tree_size while i != 1: # 1์ด๋ฉด Root ๋ ธ๋์ด๋ฏ๋ก ์ข ๋ฃ if tree[i//2] > tree[i]: tree[i//2] = tree[i] i -= 1 # a๋ฒ์งธ๋ถํฐ b๋ฒ์งธ ๊ฐ ์ค์์ ์ต์๊ฐ ๊ตฌํ๊ธฐ start, end = a + (2**k - 1), b + (2**k - 1) # ์ง์ index๋ฅผ ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ์ index๋ก ๋ณ๊ฒฝ selected_nums = [] while start <= end: if start % 2 == 1: selected_nums.append(tree[start]) start += 1 if end % 2 == 0: selected_nums.append(tree[end]) end -= 1 start = start // 2 end = end // 2 answer = sum(selected_nums) answer = max(selected_nums) answer = min(selected_nums)
์์ด
-
๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์ฉ ์ฝ๋
from itertools import permutations li1 = [1,2,3,4] permutations(li1) # 4! permutations(li1, r=2) # 4P2
- ๊ฒฐ๊ณผ๋ก ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ฏ๋ก list()๋ฅผ ์์์ฃผ์. ๋ด๋ถ ๊ฐ๋ค์ ํํ ํํ์ด๋ค.
-
n๊ฐ์ ์๋ก ์์ด์ ๋ง๋๋ ์ํฉ์์, ๋ค์์ ์ด์ฉํ์.
- 1๋ฒ์งธ ์๋ฆฟ์๊ฐ ์ ํด์ก๋ค๊ณ ๊ฐ์ ํ์ ๋, ๊ทธ ๋ค์์ ์ฌ ์ ์๋ ๊ฒฝ์ฐ์ ์๋ (n-1)!์ด๋ค.
- 2๋ฒ์งธ ์๋ฆฟ์๊ฐ ์ ํด์ก๋ค๊ณ ๊ฐ์ ํ์ ๋, ๊ทธ ๋ค์์ ์ฌ ์ ์๋ ๊ฒฝ์ฐ์ ์๋ (n-2)!์ด๋ค.
- ...
- ์ฐธ๊ณ ๋ธ๋ก๊ทธ
๋์ ๊ณํ๋ฒ (Dynamic Programming)
: ๋ณต์กํ ๋ฌธ์ ๋ฅผ ์ฌ๋ฌ ๊ฐ์ ๊ฐ๋จํ ๋ฌธ์ ๋ก ๋ถ๋ฆฌํ๊ณ , ๋ถ๋ถ ๋ฌธ์ ๋ค์ ํด๊ฒฐํจ์ผ๋ก์จ ์ต์ข ์ ์ธ ๋ฌธ์ ์ ๋ต์ ๊ตฌํ๋ ๋ฐฉ๋ฒ
-
ํฐ ๋ฌธ์ ๋ฅผ ์์ ๋ฌธ์ ๋ก ๋๋ ์ ์์ด์ผํจ
-
์์ ๋ฌธ์ ๋ค์ด ๋ฐ๋ณต์ ์ผ๋ก ๋ํ๋๊ณ ์ฌ์ฉ๋๋ฉฐ, ์ด ๊ฒฐ๊ณผ๊ฐ์ ํญ์ ๊ฐ์์ผํจ
-
๋ชจ๋ ์์ ๋ฌธ์ ์ ๊ฒฐ๊ณผ๊ฐ์ ํ๋ฒ๋ง ๊ณ์ฐํ์ฌ DP ํ ์ด๋ธ์ ์ ์ฅ (Memoization)
-
Top-down ๋ฐฉ์ ๋๋ Bottom-up ๋ฐฉ์์ผ๋ก ๊ตฌํํ ์ ์์
- Top-down ๋ฐฉ์: ์ฃผ๋ก ์ฌ๊ทํจ์ ์ฌ์ฉ
- Bottom-up ๋ฐฉ์: ์ฃผ๋ก ๋ฐ๋ณต๋ฌธ ์ฌ์ฉ
-
๋์ ๊ณํ๋ฒ์ผ๋ก ํ ์ ์๋ค๊ณ ํ๋จํ์ผ๋ฉด ์ ํ์ ์ธ์ฐ๊ธฐ
-
๋ํ์ ์ธ ๋ฌธ์
- ํผ๋ณด๋์น ์์ด
- LCS (Longest Common Subsequence)
- ํ์ผ ์ฑ์ฐ๊ธฐ

