I about me

[이것이 코딩테스트다] 4. 정렬 본문

Algorithm/이것이 코딩테스트다!

[이것이 코딩테스트다] 4. 정렬

ssungni 2024. 7. 19. 22:31

해당 강의를 참고하여 공부를 진행했습니다.

https://www.youtube.com/watch?v=m-9pAwq1o3w&list=PLRx0vPvlEmdAghTr5mXQxGpHjWqSz0dgC


시간복잡도

  Best Average Worst 특징
선택 정렬 n^2 n^2 n^2 아이디어가 매우 간단합니다
삽입 정렬 n n^2 n^2 데이터가 거의 정렬되어 있을 깨는 가장 빠릅니다.
퀵 정렬 nlogn nlogn n^2 대부분의 경우에 가장 적합하며, 충분히 빠릅니다.
계수 정렬     N + K 데이터의 크기가 한정되어 있는 경우에만,
사용이 가능하지만 매우 빠르게 동작합니다.

 

선택 정렬

주어진 리스트 중 최솟값을 찾아, 바꿔줌으로써 정렬하는 알고리즘

i 주어진 리스트 최솟값
0 [7, 5, 9, 0, 3, 1, 6, 2, 4, 8] 0
1 [0, 5, 9, 7, 3, 1, 6, 2, 4, 8] 1
2 [0, 1, 9, 7, 3, 5, 6, 2, 4, 8] 2
3 [0, 1, 2, 7, 3, 5, 6, 9, 4, 8] 3
4 [0, 1, 2, 3, 7, 5, 6, 9, 4, 8] 4
5 [0, 1, 2, 3, 4, 5, 6, 9, 7, 8] 5
6 [0, 1, 2, 3, 4, 5, 6, 9, 7, 8] 6
7 [0, 1, 2, 3, 4, 5, 6, 9, 7, 8] 7
8 [0, 1, 2, 3, 4, 5, 6, 7, 9, 8] 8
9 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 9

 

array = [7, 5, 9, 0, 3, 1, 6, 2, 4, 8]

for i in range(len(array)):
    min_index = i
    for j in range(i+1, len(array)):
        if array[j] < array[min_index]:
            min_index = j
    array[i], array[min_index] = array[min_index], array[i]

print(array)

 

삽입 정렬

자료 배열의 모든 요소를 앞에서부터 차례대로 이미 정렬된 배열 부분과 비교하여,

자신의 위치를 찾아 삽입함으로써 정렬을 완성하는 알고리즘

i 주어진 리스트
0 [7, 5, 9, 0, 3, 1, 6, 2, 4, 8]
1 [5, 7, 9, 0, 3, 1, 6, 2, 4, 8]
2 [5, 7, 9, 0, 3, 1, 6, 2, 4, 8]
3 [0, 5, 7, 9, 3, 1, 6, 2, 4, 8]
4 [0, 3, 5, 7, 9, 1, 6, 2, 4, 8]
5 [0, 1, 3, 5, 7, 9, 6, 2, 4, 8]
6 [0, 1, 3, 5, 6, 7, 9, 2, 4, 8]
7 [0, 1, 2, 3, 5, 6, 7, 9, 4, 8]
8 [0, 1, 2, 3, 4, 5, 6, 7, 9, 8]
9 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
array = [7, 5, 9, 0, 3, 1, 6, 2, 4, 8]

for i in range(1, len(array)):
    for j in range(i, 0, -1):
        if array[j] < array[j - 1]:
            array[j], array[j - 1] = array[j - 1], array[j]
        else:
            break

print(array)

퀵 정렬

pivot을 중점으로 : p보다 큰 것, : p보다 작은 것

위치가 엇갈리는 경우, pivot과 작은 데이터의 위치를 서로 변경합니다.

i 주어진 리스트
0 [5, 7, 9, 0, 3, 1, 6, 2, 4, 8]
1 [5, 4, 9, 0, 3, 1, 6, 2, 7, 8]
2 [5, 4, 2, 0, 3, 1, 6, 9, 7, 8]
3 [1, 4, 2, 0, 3, 5 , 6, 9, 7, 8]
4 ...
array = [5, 7, 9, 0, 3, 1, 6, 2, 4, 8]

def quick_sort(array, start, end):
    if start >= end: # 원소가 1개인 경우 종료
        return
    pivot = start # 0
    left = start + 1 # 1
    right = end # 9

    # left = 1 right = 9
    while (left <= right):
        #  <-- : 피봇보다 작은 데이터를 찾을 때까지 반복
        while (left <= end and array[left] <= array[pivot]):
            left += 1
        # --> : 피봇보다 큰 데이터를 찾을 때까지 반복
        while (right > start and array[right] >= array[pivot]):
            right -= 1
        if(left > right): # 엇갈렸다면 작은 데이터와 피벗을 교체
            # right로 오는게 작은 값
            array[right], array[pivot] = array[pivot], array[right]
        else: # 엇갈리지 않았다면
            # left로 오는 큰 값
            array[left], array[right] = array[right], array[left]
    quick_sort(array, start, right-1)
    quick_sort(array, right+1, end)

quick_sort(array, 0, len(array) - 1)
print(array)

 

array = [5, 7, 9, 0, 3, 1, 6, 2, 4, 8]

def quick_sort(array):
    if len(array) <= 1:
        return array
    pivot = array[0]
    tail = array[1:]

    left_side = [x for x in tail if x <= pivot]
    right_side = [x for x in tail if x > pivot]

    return quick_sort(left_side) + [pivot] + quick_sort(right_side)

print(quick_sort(array))

계수 정렬

  • 정렬할 데이터: 7 5 9 0 3 1 6 2 9 1 4 8 0 5 2

  • 출력결과: 0 0 1 1 2 2 3 4 5 5 6 7 8 9 9
# 모든 원소의 값이 0보다 크거나 같다고 가정
array = [7, 5, 9, 0, 3, 1, 6, 2, 9, 1, 4, 8, 0, 5, 2]

# 모든 범위를 포한하는 리스트 선언(모든 값 0으로 초기화)
count = [0] * (max(array) + 1)

for i in range(len(array)):
    count[array[i]] += 1

for i in range(len(count)):
    for j in range(count[i]):
        print(i, end = ' ') # 띄어쓰기를 구분으로 등장한 횟수만큼 인텍스 출력

 

문제

N, K = map(int, input().split())
A = list(map(int, input().split()))
B = list(map(int, input().split()))

A.sort()
B.sort(reverse=True)

for i in range(K):
    # A[i] = B[i]
    if A[i] < B[i]: # A배열의 값이 작다면
        A[i], B[i] = B[i], A[i]
    else: # 크면 다 크다는 걸 증명한 것이므로 더 이상 돌릴 필요가 없어짐 그러므로 코드 필요 꼭 넣기
        break
print(sum(A))