알고리즘 스터디 정렬-2751번
study
백준 정렬 2751번
안녕하세요. GDSC 머신러닝 멤버 김민찬입니다.
파이썬은 내장되어 있는 함수가 많아, 이를 잘 활용하면 문제를 쉽게 해결할 수 있을 것 같습니다.
sort( )
아래는 제가 문제를 해결한 과정입니다.
n = int(input()) # 수의 개수
num_list = []
for i in range(n):
num_list.append(int(input()))
num_list.sort()
# sort 함수를 통해 오름차순으로 정렬 내림차순 정렬은 (reverse=True)
# sorted는 순서대로 정렬, 정렬된 리스트를 반환 ex) y = sorted(x)
for i in num_list:
print(i)
합병 정렬 (Merge sort)
문제를 너무 쉽게 해결한 것 같아서, 다른 방법에 대하여 찾아보았는데, 이 문제를 해결하기 위한 다른 방법 중 하나로 합병 정렬이 있다는 것을 알게 되었습니다.
합병 정렬의 알고리즘은 다음과 같습니다.
1. 정렬되지 않은 리스트를 각각 하나의 원소만 포함하는 n개의 부분리스트로 분할한다.
이 때, 원소가 들어있지 않거나 한 원소만 든 리스트는 정렬된 것과 같다.
2. 부분리스트가 하나만 남을 때까지 반복해서 병합하며 정렬된 부분리스트를 생성한다.
마지막 남은 부분리스트가 정렬된 리스트이다.
이를 간단하게 설명하면,
리스트가 원소가 한 개 혹은 0개인 부분리스트가 될 때까지 균등한 크기로 1/2씩 반복적으로 분할(divide)하고, 이를 결합(combine)하는 과정에서 정렬(conquer)하는 것입니다.
이 때, 두 리스트를 합병하는 과정에서 각 리스트의 첫번째 값부터 비교해가며 더 작은 값을 새로운 리스트로 옮기는 과정으로 진행됩니다.
아래는 제가 참고한 합병 정렬을 통해 2751번을 해결하는 코드입니다.
def merge_sort(array):
if len(array)<=1:
return array
# 재귀함수를 이용해서 끝까지 분할
mid = len(array)//2
left = merge_sort(array[:mid])
right = merge_sort(array[mid:])
i,j,k = 0,0,0
# 분할된 배열끼리 비교
while i<len(left) and j <len(right):
if left[i]<right[j]:
array[k] = left[i]
i += 1
else:
array[k] = right[j]
j += 1
k+=1
# 먼저 끝났을 때
if i==len(left):
while j < len(right):
array[k] = right[j]
j+=1
k+=1
elif j==len(right):
while i < len(left):
array[k] = left[i]
i+=1
k+=1
return array
n=int(input())
num_list = []
for i in range(n):
num_list.append(int(input()))
num = merge_sort(num)
for i in num:
print(i)
참고자료
https://assaeunji.github.io/python/2020-05-06-bj2751/
https://ko.wikipedia.org/wiki/%ED%95%A9%EB%B3%91_%EC%A0%95%EB%A0%AC
https://gmlwjd9405.github.io/2018/05/08/algorithm-merge-sort.html