알고리즘 연습/정렬

[🥈5 / 백준 10989 / 파이썬] 수 정렬하기 3 (카운팅 정렬)

김세진 2021. 6. 6. 22:34
반응형

 

 

10989번: 수 정렬하기 3

첫째 줄에 수의 개수 N(1 ≤ N ≤ 10,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 수가 주어진다. 이 수는 10,000보다 작거나 같은 자연수이다.

www.acmicpc.net

 

문제

N개의 수가 주어졌을 때, 이를 오름차순으로 정렬하는 프로그램을 작성하시오.

입력

첫째 줄에 수의 개수 N(1 ≤ N ≤ 10,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 숫자가 주어진다. 이 수는 10,000보다 작거나 같은 자연수이다.

출력

첫째 줄부터 N개의 줄에 오름차순으로 정렬한 결과를 한 줄에 하나씩 출력한다.

 

예제 입력

10
5
2
3
1
4
2
3
5
1
7

예제 출력

1
1
2
2
3
3
4
5
5
7

 

풀이

 

 

카운팅 정렬을 이용하는 문제이다.

 

카운팅 정렬은 수의 범위가 작을 때 빠르게 정렬할 수 있는 방법이다.

 

아래 링크는 카운팅 정렬의 알고리즘을 자세히 보여준다.

 

http://www.cs.miami.edu/home/burt/learning/Csc517.091/workbook/countingsort.html

 

Counting Sort

This is an animation of the counting sort algorithm found in CLR's Algorithms book. Array C (counting array): PSEUDOCODE FOR COUNTING SORT (taken from CLR) Initialize counting array to all zeros. Count the number of times each value occurs in the input. Mo

www.cs.miami.edu

 

위 알고리즘의 형태를 그대로 따라 코드를 작성해보았다.

 

import sys
numCount = int(sys.stdin.readline())
nums = [int(sys.stdin.readline()) for i in range(numCount)]
count = [0] * max(nums)
sorted_list = [0] * numCount

for i in nums:
    count[i-1] += 1

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

for i in range(len(nums)-1, -1, -1):
    sorted_list[count[nums[i]-1]-1] = nums[i]
    count[nums[i]-1] -= 1
                
for i in sorted_list:
    print(i)

 

테스트 케이스에선 정렬이 정상 작동 하였으나, 제출을 시도하면 메모리 초과가 발생한다.

 

큰 배열을 두 개나 생성해야 해서 그런 것 같다.

 

그래서 누적합을 지워주고 nums와 count를 하나로 합쳐보도록 했다.

 

import sys
count = [0] * 10001	# 10000 이하의 자연수

for i in range(int(input())):
    count[int(input())] += 1

for i in range(len(count)):
    while count[i] > 0:
        print(i)
        count[i] -=1

 

 

결과

 

 

반응형