Search

μ‹œκ°„λ³΅μž‘λ„

Created At
2022/01/25 23:21
Updated At
2022/03/14 09:51
λΆ„λ₯˜
기타
λ‹€λ₯Έ κ°œλ°œμžλ“€κ³Ό ν•¨κ»˜ μ•Œκ³ λ¦¬μ¦˜μ— λŒ€ν•œ μ˜λ…Όμ„ ν•˜κ²Œ 되면, μžμ—°μŠ€λŸ½κ²Œ β€œμ‹œκ°„ λ³΅μž‘λ„β€ 이야기가 λ‚˜μ˜¬ μˆ˜λ°–μ— μ—†μŠ΅λ‹ˆλ‹€. μ‹œκ°„ λ³΅μž‘λ„λ₯Ό 계산할 쀄 μ•Œμ•„μ•Ό μ›ν™œν•œ λŒ€ν™”κ°€ μ΄λ£¨μ–΄μ§ˆ 수 있겠죠.
λ‹€ν–‰νžˆ, μ•Œκ³ λ¦¬μ¦˜μ˜ μ‹œκ°„ λ³΅μž‘λ„λŠ” λŒ€κ°œ 이 쀑 ν•˜λ‚˜μž…λ‹ˆλ‹€.
β€’
O(1)
β€’
O(lgn)
β€’
O(n)
β€’
O(nlgn)
β€’
O(n^2)
β€’
O(n^3)
β€’
O(n^4)
β€’
O(2^n)
β€’
O(n!)
이 μ€‘μ—μ„œλ„ O(1), O(lgn), O(n), O(nlgn), O(n^2), O(n^3) 정도가 많이 μ‚¬μš©λ˜κ³ , λ‚˜λ¨Έμ§€λŠ” ν”μΉ˜ μ•ŠμŠ΅λ‹ˆλ‹€.

O(1)

O(1)O(1)은 μΈν’‹μ˜ 크기가 μ†Œμš” μ‹œκ°„μ— 영ν–₯이 μ—†λ‹€λŠ” λœ»μž…λ‹ˆλ‹€.
# O(1) ν•¨μˆ˜def print_first(my_list): print(my_list[0]) print_first([2, 3]) print_first([2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53])
Plain Text
볡사
print_first ν•¨μˆ˜λ₯Ό 처음 ν˜ΈμΆœν•  λ•ŒλŠ” μš”μ†Œκ°€ 2κ°œλ°–μ— μ—†λŠ” 리슀트λ₯Ό λ„˜κ²¨μ€¬λŠ”λ°, 두 번째 ν˜ΈμΆœν•  λ•ŒλŠ” μš”μ†Œκ°€ 16개 μžˆλŠ” 리슀트λ₯Ό λ„˜κ²¨μ€¬μŠ΅λ‹ˆλ‹€. 그런데 사싀 두 경우 κ±Έλ¦¬λŠ” μ‹œκ°„μ€ 거의 λ˜‘κ°™μŠ΅λ‹ˆλ‹€. μ–΄μ°¨ν”Ό 맨 μ•žμ— μžˆλŠ” μš”μ†Œλ₯Ό λ°›μ•„μ˜€λŠ” 것 λΏμ΄λ‹ˆκΉŒ, 리슀트의 κΈΈμ΄λŠ” 상관이 μ—†λŠ” κ±°μ£ . 길이가 10λ§Œμ”©μ΄λ‚˜ λ˜λŠ” 리슀트λ₯Ό λ„˜κ²¨μ€˜λ„ λ˜‘κ°™μ„ κ²ƒμž…λ‹ˆλ‹€.
λ‚˜λ¦„μ˜ νŒμ„ λ“œλ¦¬μžλ©΄, 반볡문이 μ—†μœΌλ©΄ λŒ€μ²΄λ‘œ O(1)O(1)μž…λ‹ˆλ‹€.

O(n)

Case 1

# O(n) ν•¨μˆ˜def print_each(my_list): for i in range(len(my_list)): print(my_list[i])
Plain Text
볡사
반볡문이 있고, λ°˜λ³΅λ˜λŠ” νšŸμˆ˜κ°€ μΈν’‹μ˜ 크기와 λΉ„λ‘€ν•˜λ©΄ 일반적으둜 O(n)O(n)μž…λ‹ˆλ‹€.

Case 2

# O(n) ν•¨μˆ˜def print_half(my_list): for i in range(len(my_list) // 2): print(my_list[i])
Plain Text
볡사
nn번 λ°˜λ³΅ν•˜λŠ” 게 μ•„λ‹ˆλΌ n/2n/2번 λ°˜λ³΅ν•œλ‹€λ©΄ μ‹œκ°„ λ³΅μž‘λ„κ°€ μ–΄λ–»κ²Œ λ κΉŒμš”? O(\frac{1}{2}n)O(21n)μ΄μ§€λ§Œ, \frac{1}{2}21을 λ²„λ €μ„œ κ²°λ‘ μ μœΌλ‘œλŠ” O(n)O(n)이라고 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Case 3

# O(n) ν•¨μˆ˜def print_three_times(my_list): for i in range(len(my_list)): print(my_list[i]) for i in range(len(my_list)): print(my_list[i]) for i in range(len(my_list)): print(my_list[i])
Plain Text
볡사
μœ„ μ½”λ“œμ˜ 경우 O(3n)O(3n)인데, κ²°κ΅­μ—λŠ” 33을 λ²„λ €μ„œ 이것 λ˜ν•œ O(n)O(n)이라고 ν•  수 있겠죠?

O(n^2)

그런데 반볡문이 μ—°μ†ν•΄μ„œ λ‚˜μ˜€λŠ” 게 μ•„λ‹ˆλΌ, 반볡문 μ•ˆμ— 반볡문이 μžˆλŠ” κ²½μš°κ°€ μžˆμŠ΅λ‹ˆλ‹€.
# O(n^2) ν•¨μˆ˜def print_pairs(my_list): for i in range(len(my_list)): for j in range(len(my_list)): print(my_list[i], my_list[j])
Plain Text
볡사
μ§€κΈˆμ²˜λŸΌ 두 반볡문 λ‹€ μΈν’‹μ˜ 크기에 λΉ„λ‘€ν•˜λŠ” 경우, O(n^2)O(n2)이라고 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

O(n^3)

# O(n^3) ν•¨μˆ˜def print_triplets(my_list): for i in range(len(my_list)): for j in range(len(my_list)): for k in range(len(my_list)): print(my_list[i], my_list[j], my_list[k])
Plain Text
볡사
λ™μΌν•œ μ›λ¦¬λ‘œ, μΈν’‹μ˜ 크기에 λΉ„λ‘€ν•˜λŠ” 반볡문이 μ„Έ 번 μ€‘μ²©λ˜λ©΄ O(n^3)O(n3)이 되겠죠?

O(lgn)

Case 1

# O(lg n) ν•¨μˆ˜# 2의 κ±°λ“­μ œκ³±μ„ 좜λ ₯ν•˜λŠ” ν•¨μˆ˜# (μ΄λ²ˆμ—λŠ” 인풋이 λ¦¬μŠ€νŠΈκ°€ μ•„λ‹ˆλΌ κ·Έλƒ₯ μ •μˆ˜μž…λ‹ˆλ‹€)def print_powers_of_two(n): i = 1 while i < n: print(i) i = i * 2
Plain Text
볡사
μ΄λ²ˆμ—λŠ” 반볡문이 쑰금 νŠΉμ΄ν•©λ‹ˆλ‹€. iκ°€ 두 λ°°μ”© μ¦κ°€ν•˜λ„€μš”.
인풋 n이 128이면 반볡문이 총 λͺ‡ 번 μ‹€ν–‰λ κΉŒμš”? iκ°€ 1일 λ•ŒλΆ€ν„° 2, 4, 8, 16, 32, 64κΉŒμ§€ 총 7번 μ‹€ν–‰λ©λ‹ˆλ‹€. \lg{128}lg128도 77인 건 μš°μ—°μ΄ μ•„λ‹™λ‹ˆλ‹€!
print_powers_of_two ν•¨μˆ˜λŠ” O(\lg{n})O(lgn)μž…λ‹ˆλ‹€.

Case 2

# O(lg n) ν•¨μˆ˜# 2의 κ±°λ“­μ œκ³±μ„ 좜λ ₯ν•˜λŠ” ν•¨μˆ˜# (μ΄λ²ˆμ—λŠ” 인풋이 λ¦¬μŠ€νŠΈκ°€ μ•„λ‹ˆλΌ κ·Έλƒ₯ μ •μˆ˜μž…λ‹ˆλ‹€)def print_powers_of_two(n): i = n while i > 1: print(i) i = i / 2
Plain Text
볡사
iλ₯Ό 1λΆ€ν„° μ‹œμž‘ν•΄μ„œ 두 λ°°μ”© κ³±ν•˜λŠ” 게 μ•„λ‹ˆλΌ, nλΆ€ν„° μ‹œμž‘ν•΄μ„œ λ°˜μ”© λ‚˜λˆ λ΄…μ‹œλ‹€. 이 κ²½μš°μ—λ„ iκ°€ 128일 λ•ŒλΆ€ν„° 64, 32, 16, 8, 4, 2κΉŒμ§€ 반볡문이 7번 μ‹€ν–‰λ©λ‹ˆλ‹€.
두 경우 λͺ¨λ‘ O(\lg{n})O(lgn)μž…λ‹ˆλ‹€.

O(nlgn)

O(n^2)O(n2)은 O(n)O(n)κ³Ό O(n)O(n)이 μ€‘μ²©λœ κ±°μ£ ? 같은 λ…Όλ¦¬λ‘œ, O(n\lg{n})O(nlgn)은 O(n)O(n)κ³Ό O(\lg{n})O(lgn)이 겹쳐진 κ²ƒμž…λ‹ˆλ‹€.

Case 1

def print_powers_of_two_repeatedly(n): for i in range(n): # 반볡횟수: n에 λΉ„λ‘€ j = 1 while j < n: # 반볡횟수: lg n에 λΉ„λ‘€ print(i, j) j = j * 2
Plain Text
볡사
μœ„ μ½”λ“œμ—μ„œ for문의 λ°˜λ³΅νšŸμˆ˜λŠ” nn에 λΉ„λ‘€ν•˜λŠ”λ°, while문의 λ°˜λ³΅νšŸμˆ˜λŠ” \lg{n}lgn에 λΉ„λ‘€ν•©λ‹ˆλ‹€. while문이 forλ¬Έ μ•ˆμ— μ€‘μ²©λ˜μ–΄ 있기 λ•Œλ¬Έμ— μœ„ μ½”λ“œμ˜ μ‹œκ°„ λ³΅μž‘λ„λŠ” O(n\lg{n})O(nlgn)이라고 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Case 2

def print_powers_of_two_repeatedly(n): i = 1 while i < n: # 반볡횟수: lg n에 λΉ„λ‘€for j in range(n): # 반볡횟수: n에 λΉ„λ‘€ print(i, j) i = i * 2
Plain Text
볡사
Case 1의 μ½”λ“œλ₯Ό 살짝 λ°”κΏ”μ„œ 이제 for문이 whileλ¬Έ μ•ˆμ— μ€‘μ²©λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. 이 κ²½μš°μ—λ„ μ‹œκ°„ λ³΅μž‘λ„λŠ” O(n\lg{n})O(nlgn)μž…λ‹ˆλ‹€.