백준 10989: 수 정렬하기 3과 카운팅 정렬
백준 10989번 수 정렬하기 3은 시간과 메모리 제한을 함께 고려해야 하는 문제였습니다. 입력값의 범위가 1부터 10,000까지라는 점을 이용해 카운팅 정렬로 풀었습니다.
값을 저장하는 대신 횟수를 셉니다
크기가 10,000인 배열을 만들고 입력값에서 1을 뺀 위치의 횟수를 늘립니다. 입력이 끝나면 배열의 앞에서부터 순회하며 각 값을 등장한 횟수만큼 출력합니다. 배열 인덱스는 0부터 시작하므로 출력할 때는 다시 1을 더합니다.
카운트 배열의 크기는 고정되어 있지만 이 코드는 출력 전체를 StringBuilder에 모읍니다. 그래서 전체 메모리 사용량까지 고정 크기라고 볼 수는 없습니다.
입력을 마친 뒤에는 br.close()로 자원을 닫았습니다. 당시 주석에서는 이를 가비지 컬렉터와 연결했지만, BufferedReader.close()는 스트림을 닫고 연결된 시스템 자원을 해제하는 메서드입니다. 이 호출은 가비지 컬렉션을 실행하지 않으며 프로그램 전체의 메모리 사용량 문제를 해결해 주지도 않습니다.
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int N = Integer.parseInt(br.readLine());
// 0~9999 의 범위 따라서 출력할 때 1을 더해서 출력
int[] arr = new int[10000];
for (int i = 0; i < N; i++) {
arr[Integer.parseInt(br.readLine())-1]++;
}
//입력 끝나면 닫아주기, Garbage Collector를 너무 의존하지 말자
br.close();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
while (arr[i] > 0) {
sb.append(i+1).append("\n");
arr[i]--;
}
}
bw.write(sb.toString());
bw.flush();
}
}