[Algorithm] ์ •๋ ฌ | ์„ ํƒ ์ •๋ ฌ, ์‚ฝ์ž… ์ •๋ ฌ, ํ€ต ์ •๋ ฌ, ๊ณ„์ˆ˜ ์ •๋ ฌ
๐Ÿ–ฅ CS/Algorithm

[Algorithm] ์ •๋ ฌ | ์„ ํƒ ์ •๋ ฌ, ์‚ฝ์ž… ์ •๋ ฌ, ํ€ต ์ •๋ ฌ, ๊ณ„์ˆ˜ ์ •๋ ฌ

์ •๋ ฌ์ด๋ž€ ์ฃผ์–ด์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ํŠน์ • ๊ธฐ์ค€์— ๋”ฐ๋ผ ์ˆœ์„œ๋Œ€๋กœ ๋‚˜์—ดํ•˜์—ฌ ์žฌ๋ฐฐ์น˜ํ•˜๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.

์ •๋ ฌ๋œ ๋ฐฐ์—ด์—์„œ ์›ํ•˜๋Š” ๊ฐ’์„ ํƒ์ƒ‰ํ•˜๋Š” ์ด์ง„ ํƒ์ƒ‰(Binary Search)๋ฅผ ์œ„ํ•ด์„œ๋Š” ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ž˜ ์•Œ์•„๋‘์–ด์•ผ ํ•œ๋‹ค.

 

 

1. ์„ ํƒ ์ •๋ ฌ

 

๐Ÿ“Œ ๊ฐ€์žฅ ์ž‘์€ ๋ฐ์ดํ„ฐ๋ฅผ ์„ ํƒํ•ด ๋งจ ์•ž์— ์žˆ๋Š” ๋ฐ์ดํ„ฐ์™€ ๊ตํ™˜ํ•˜๋Š” ๊ณผ์ •์„ ๋ฐ˜๋ณต

 

swap(๋ฆฌ์ŠคํŠธ์—์„œ ๋‘ ์›์†Œ์˜ ์œ„์น˜๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์ž‘์—…)์„ ์ด์šฉํ•˜๋ฉด ์„ ํƒ์ •๋ ฌ์„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

arr = [4,3,1,7,2,8,6,5]

for i in range(len(arr)):
	min_index = i # ์šฐ์„  ๊ฐ€์žฅ ์ž‘์€ ์›์†Œ์˜ ์ธ๋ฑ์Šค๋กœ ๋งจ ์•ž์˜ ์›์†Œ๋ฅผ ์ง€์ •
    for j in range(i+1, len(arr)): # ๋งจ ์•ž ์›์†Œ ์ œ์™ธ
    	if arr[min_index] > arr[j]: # ๊ฐ€์žฅ ์ž‘์€ ์›์†Œ๋กœ ์ง€์ •ํ•œ ์›์†Œ๋ณด๋‹ค ๋” ์ž‘์€ ์›์†Œ๊ฐ€ ์žˆ๋‹ค๋ฉด
        	min_index = j # ์ด์ œ๋ถ€ํ„ฐ ๊ทธ ์›์†Œ์˜ ์ธ๋ฑ์Šค๊ฐ€ ๊ฐ€์žฅ ์ž‘์€ ์›์†Œ์˜ ์ธ๋ฑ์Šค
    
    arr[i], arr[min_index] = arr[min_index], arr[i] # swap

 

๐Ÿ“Œ ์„ ํƒ ์ •๋ ฌ์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„: O(N^2)

→ ํƒ์ƒ‰ ๋ฒ”์œ„๊ฐ€ N์—์„œ 1์”ฉ ์ค„์–ด๋“ค๊ธฐ ๋•Œ๋ฌธ์—, ์•„๋ž˜ ์ˆ˜์‹์„ ๋”ฐ๋ฅธ๋‹ค.

 

 

2. ์‚ฝ์ž… ์ •๋ ฌ

 

๐Ÿ“Œ ํŠน์ •ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฅผ ์ ์ ˆํ•œ ์œ„์น˜์— ์‚ฝ์ž…ํ•œ๋‹ค.

 

 

arr = [4,3,1,7,2,8,6,5]

for i in range(1, len(arr)):
	for j in range(i, 0, -1) # ์ธ๋ฑ์Šค i๋ถ€ํ„ฐ 1๊นŒ์ง€ ๊ฐ์†Œํ•˜์—ฌ ๋ฐ˜๋ณตํ•˜๋Š” ์ˆ˜์—ด(=ํ•œ ์นธ์”ฉ ์™ผ์ชฝ์œผ๋กœ ์ด๋™)
    	if arr[j] < arr[j-1]: # ๋‚˜๋ณด๋‹ค ํฐ ๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋‚˜๋ฉด
        	arr[j], arr[j-1] = arr[j-1], arr[j] # ๋งŒ๋‚œ ๋ฐ์ดํ„ฐ๋ž‘ ์œ„์น˜ ๋ณ€๊ฒฝ
        else: # ๋‚˜๋ณด๋‹ค ์ž‘์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋‚˜๋ฉด ๋ฉˆ์ถค
        	break

 

๐Ÿ“Œ ์‚ฝ์ž… ์ •๋ ฌ์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„: O(N^2)

โ€ป ์ •๋ ฌํ•ด์•ผํ•˜๋Š” ๋ฆฌ์ŠคํŠธ๊ฐ€ ๊ฑฐ์˜ ์ •๋ ฌ๋˜์–ด์žˆ๋Š” ์ƒํƒœ: O(N) → ์ด ๊ฒฝ์šฐ์—๋Š” ํ€ต์ •๋ ฌ๋ณด๋‹ค ์‚ฝ์ž… ์ •๋ ฌ์˜ ํšจ๊ณผ ๊ฐ•๋ ฅ

 

 

3. ํ€ต ์ •๋ ฌ

 

๐Ÿ“Œ ํ”ผ๋ฒ—(๊ธฐ์ค€์ด ๋˜๋Š” ๋ฐ์ดํ„ฐ)๋ฅผ ์„ค์ •ํ•˜๊ณ  ๊ทธ ๊ธฐ์ค€๋ณด๋‹ค ํฐ ๋ฐ์ดํ„ฐ์™€ ์ž‘์€ ๋ฐ์ดํ„ฐ์˜ ์œ„์น˜๋ฅผ ๋ฐ”๊พผ๋‹ค. 

 

 

โ€ป ํ˜ธ์–ด ๋ถ„ํ•  ๋ฐฉ์‹์˜ ํ€ต ์ •๋ ฌ → ๋ฆฌ์ŠคํŠธ์—์„œ ์ฒซ ๋ฒˆ์งธ ๋ฐ์ดํ„ฐ๋ฅผ ํ”ผ๋ฒ—์œผ๋กœ ๊ฒฐ์ •

 

(1) ์™ผ์ชฝ์—์„œ๋ถ€ํ„ฐ ํ”ผ๋ฒ—๋ณด๋‹ค ํฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ๊ณ , ์˜ค๋ฅธ์ชฝ์—์„œ๋ถ€ํ„ฐ ํ”ผ๋ฒ—๋ณด๋‹ค ์ž‘์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ๋Š”๋‹ค.  

(2) ์–‘์ชฝ์—์„œ ์ฐพ์•˜๋‹ค๋ฉด ๋‘ ๋ฐ์ดํ„ฐ์˜ ์œ„์น˜๋ฅผ ์„œ๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.

(3) ์™ผ์ชฝ์—์„œ ์ฐพ๋Š” ๊ฐ’๊ณผ ์˜ค๋ฅธ์ชฝ์—์„œ๋ถ€ํ„ฐ ์ฐพ๋Š” ๊ฐ’์˜ ์œ„์น˜๊ฐ€ ์—‡๊ฐˆ๋ ธ๋‹ค๋ฉด(์˜ˆ์‹œ ์ฐธ๊ณ ) ๋‘˜ ์ค‘ ์ž‘์€ ๋ฐ์ดํ„ฐ์™€ ํ”ผ๋ฒ—์˜ ์œ„์น˜๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค.

(4) ์ด๋™ํ•œ ํ”ผ๋ฒ—์„ ๊ธฐ์ค€์œผ๋กœ ์™ผ์ชฝ ๋ฆฌ์ŠคํŠธ์™€ ์˜ค๋ฅธ์ชฝ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋‚˜๋‰œ๋‹ค. ๊ฐ๊ฐ ํ€ต ์ •๋ ฌ์„ ๋‹ค์‹œ ์ˆ˜ํ–‰ํ•ด์ค€๋‹ค.

(5) ํ˜„์žฌ ๋ฆฌ์ŠคํŠธ์˜ ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜๊ฐ€ 1๊ฐœ๋ฉด ํ€ต ์ •๋ ฌ์ด ์ข…๋ฃŒ๋œ๋‹ค.

 

 

Case1.

 

arr = [4,3,1,7,2,8,6,5]

def quick_sort(arr, start, end):
	if start >= end:
    	return
    
    pivot = start # ์ฒซ ๋ฒˆ์งธ ์›์†Œ๋ฅผ ํ”ผ๋ฒ—์œผ๋กœ ์„ค์ •
    left = start + 1 # ์™ผ์ชฝ์—์„œ๋ถ€ํ„ฐ ๊ณ ๊ณ 
    right = end # ์˜ค๋ฅธ์ชฝ์—์„œ๋ถ€ํ„ฐ ๊ณ ๊ณ 
    
    while left <= right: # ํ™”์‚ดํ‘œ ์—‡๊ฐˆ๋ฆฌ์ง€ ์•Š๋Š” ๋™์•ˆ
    	# left๊ฐ€ ๋์— ๋‹ฟ์ง€ ์•Š๊ณ  left ์›์†Œ๊ฐ€ ํ”ผ๋ด‡๋ณด๋‹ค ์ž‘์œผ๋ฉด keep going 
    	while left <= end and arr[left] <= arr[pivot]:
        	left += 1 # ํ”ผ๋ด‡๋ณด๋‹ค ํฐ ์›์†Œ๋ฅผ ์ฐพ์•„์•ผ ํ•˜๊ธฐ๋•Œ๋ฌธ์— ๊ณ„์† ์˜ค๋ฅธ์ชฝ์œผ๋กœ ๊ณ„์† ์ด๋™
            
        # left๊ฐ€ start์— ๋‹ฟ์ง€ ์•Š๊ณ  right ์›์†Œ๊ฐ€ ํ”ผ๋ด‡๋ณด๋‹ค ํฌ๋ฉด keep going
        while right > start and arr[right] >= arr[pivot]:
        	right -= 1 # ํ”ผ๋ด‡๋ณด๋‹ค ์ž‘์€ ์›์†Œ๋ฅผ ์ฐพ์•„์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ณ„์†์™ผ์ชฝ์œผ๋กœ ๊ณ„์† ์ด๋™
            
        if left > right: # ์—‡๊ฐˆ๋ ธ๋‹ค๋ฉด ์ž‘์€ ๋ฐ์ดํ„ฐ์™€ ํ”ผ๋ฒ— ์œ„์น˜ ๊ตํ™˜
        	arr[right], arr[pivot] = arr[pivot], arr[right]
        
        else: # ์—‡๊ฐˆ๋ฆฌ์ง€ ์•Š์•˜๋‹ค๋ฉด ์ž‘์€ ๋ฐ์ดํ„ฐ์™€ ํฐ ๋ฐ์ดํ„ฐ ๊ต์ฒด
        	arr[left], arr[right] = arr[right], arr[left]
   
	# right๊ฐ€ ์ด์ œ (์ „)ํ”ผ๋ด‡์ด๋ฏ€๋กœ right๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋‹ค์‹œ ์ˆ˜ํ–‰
	quick_sort(arr, start, right - 1)
	quick_sort(arr, right + 1, end) 
    

quick_sort(arr, 0, len(arr)-1)

 

 

Case2.

 

arr = [4,3,1,7,2,8,6,5]

def quick_sort(arr):
	if len(arr) <= 1:
    	return arr
        
    pivot = arr[0]
    tail = arr[1:] # ํ”ผ๋ฒ—์„ ์ œ์™ธํ•œ ๋ฆฌ์ŠคํŠธ
    
    left_arr = [x for x in tail if x <= pivot] # ๋ถ„ํ• ๋œ ์™ผ์ชฝ ๋ถ€๋ถ„ -> ํ”ผ๋ด‡๋ณด๋‹ค ์ž‘์€ ์›์†Œ๋“ค
    right_arr = [x for x in tail if x > pivot] # ๋ถ„ํ• ๋œ ์˜ค๋ฅธ์ชฝ ๋ถ€๋ถ„ -> ํ”ผ๋ด‡๋ณด๋‹ค ํฐ ์›์†Œ๋“ค
    
    return quick_sort(left_arr) + [pivot] + quick_sort(right_arr)
    
    
quick_sort(arr)

 

 

๐Ÿ“Œ ํ€ต ์ •๋ ฌ์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„: O(NlogN)

 

โ€ป ์ตœ์•…์˜ ๊ฒฝ์šฐ ์‹œ๊ฐ„ ๋ณต์žก๋„ O(N^2)

→ ํ”ผ๋ฒ—์„ ๋ฆฌ์ŠคํŠธ์˜ ๊ฐ€์žฅ ์™ผ์ชฝ ๋ฐ์ดํ„ฐ๋กœ ์ •ํ•  ๋•Œ ์ด๋ฏธ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์ •๋ ฌ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ (์‚ฝ์ž… ์ •๋ ฌ๊ณผ ๋ฐ˜๋Œ€๋กœ ๋™์ž‘)

 

 

4. ๊ณ„์ˆ˜ ์ •๋ ฌ

 

๐Ÿ“Œ ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ ๋ฒ”์œ„๊ฐ€ ์ œํ•œ๋˜์–ด ์ •์ˆ˜ ํ˜•ํƒœ๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์„ ๋•Œ, ๋ณ„๋„์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ์„ ์–ธํ•ด ๋ฐ์ดํ„ฐ์˜ ๊ฐœ์ˆ˜๋ฅผ ๋‹ด์•„ ์ •๋ ฌ์— ์‚ฌ์šฉํ•œ๋‹ค.

 

 

arr = [4,3,1,2,3,2,1,2,0]

count = [0] * (max(arr) + 1)

for i in range(len(arr)):
	count[arr[i]] += 1
    
for i in range(len(count)):
	for j in range(count[i]):
    	print(i, end=' '))

 

 

๐Ÿ“Œ ๊ณ„์ˆ˜ ์ •๋ ฌ์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„: O(N+K) ๋ณด์žฅ  → ๋ฐ์ดํ„ฐ์˜ ๊ฐœ์ˆ˜: N, ๋ฐ์ดํ„ฐ ์ค‘ ์ตœ๋Œ€๊ฐ’์˜ ํฌ๊ธฐ: K

 

 

๐Ÿ“Œ ๊ณ„์ˆ˜ ์ •๋ ฌ์˜ ๊ณต๊ฐ„ ๋ณต์žก๋„: O(N+K) → ๋ฐ์ดํ„ฐ์˜ ๊ฐœ์ˆ˜: N, ๋ฐ์ดํ„ฐ ์ค‘ ์ตœ๋Œ€๊ฐ’์˜ ํฌ๊ธฐ: K

 

→ ๋ฐ์ดํ„ฐ๊ฐ€ 0๊ณผ 999,999 ๋‹จ 2๊ฐœ์ผ ๊ฒฝ์šฐ ์‹ฌ๊ฐํ•œ ๋น„ํšจ์œจ์„ฑ ์ดˆ๋ž˜

→ ๋™์ผํ•œ ๊ฐ’์„ ๊ฐ€์ง€๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ ๋“ฑ์žฅํ•  ๋•Œ ํšจ์œจ์  

 

 

5. ํŒŒ์ด์ฌ์˜ ์ •๋ ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

 

ํŒŒ์ด์ฌ์˜ ๋‚ด์žฅ ํ•จ์ˆ˜์ธ sort()๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ์‹œ๊ฐ„ ๋ณต์žก๋„ O(NlogN) ๋ณด์žฅ

 

 

 

โ€ป  ๋ณธ ๊ฒŒ์‹œ๊ธ€์€ ์ด๊ฒƒ์ด ์ทจ์—…์„ ์œ„ํ•œ ์ฝ”๋”ฉํ…Œ์ŠคํŠธ๋‹ค with ํŒŒ์ด์ฌ์„ ์ฐธ๊ณ ํ•˜์—ฌ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.