오늘 풀어볼 문제는 백준 2751번 문제 "수 정렬하기 2" 이다.
이 문제는 실버5 문제이고 병합 정렬 문제이다.
문제
N개의 수가 주어졌을 때, 이를 오름차순으로 정렬하는 프로그램을 작성하시오.
입력
첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)이 주어진다.
둘째 줄부터 N개의 줄에는 수가 주어진다.
이 수는 절댓값이 1,000,000보다 작거나 같은 정수이다. 수는 중복되지 않는다.
출력
첫째 줄부터 N개의 줄에 오름차순으로 정렬한 결과를 한 줄에 하나씩 출력한다.
📌첫 번째 도전📌
처음 이 문제를 풀 때 그냥 sort 라이브러리를 활용해서 해결하려 했다.
public class Main {
static int[] arr;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
arr = new int[N+1];
for(int i=1; i<=N; i++) {
st = new StringTokenizer(br.readLine());
arr[i] = Integer.parseInt(st.nextToken());
}
Arrays.sort(arr);
for(int i=1; i<=N; i++) {
System.out.println(arr[i]);
}
}
}
하지만 시간 초과도 아니고 틀렸다는 결과가 나왔다. 그래서 이 방법은 아니구나를 깨달았다.
📌두 번째 도전📌
두 번째에는 병합 정렬을 활용했다.
public class Main {
static int[] arr;
static int[] tmp;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
arr = new int[N+1];
tmp = new int[N+1];
for(int i=1; i<=N; i++) {
st = new StringTokenizer(br.readLine());
arr[i] = Integer.parseInt(st.nextToken());
}
merge_sort(1, N);
for(int i=1; i<=N; i++) {
System.out.println(arr[i]);
}
}
private static void merge_sort(int start, int end) {
if (end - start < 1) {
return;
}
int m = start + (end - start) / 2;
merge_sort(start, m);
merge_sort(m+1, end);
for(int i = start; i <= end; i++) {
tmp[i] = arr[i];
}
int k = start;
int index1 = start;
int index2 = m + 1;
while (index1 <= m && index2 <= end) {
if(tmp[index1] > tmp[index2]) {
arr[k] = tmp[index2];
k++;
index2++;
} else {
arr[k] = tmp[index1];
k++;
index1++;
}
}
while (index1 <= m) {
arr[k] = tmp[index1];
k++;
index1++;
}
while (index2 <= end) {
arr[k] = tmp[index2];
k++;
index2++;
}
}
}
이번엔 시간 초과가 떴다...
📌세 번째 도전📌
그래서 BufferWriter을 활용해서 시간을 줄여보기로 했다.
public class Main {
static int[] arr;
static int[] tmp;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int N = Integer.parseInt(st.nextToken());
arr = new int[N+1];
tmp = new int[N+1];
for(int i=1; i<=N; i++) {
st = new StringTokenizer(br.readLine());
arr[i] = Integer.parseInt(st.nextToken());
}
merge_sort(1, N);
for(int i=1; i<=N; i++) {
bw.write(arr[i] + "\n");
}
bw.flush();
bw.close();
}
private static void merge_sort(int start, int end) {
if (end - start < 1) {
return;
}
int m = start + (end - start) / 2;
merge_sort(start, m);
merge_sort(m+1, end);
for(int i = start; i <= end; i++) {
tmp[i] = arr[i];
}
int k = start;
int index1 = start;
int index2 = m + 1;
while (index1 <= m && index2 <= end) {
if(tmp[index1] > tmp[index2]) {
arr[k] = tmp[index2];
k++;
index2++;
} else {
arr[k] = tmp[index1];
k++;
index1++;
}
}
while (index1 <= m) {
arr[k] = tmp[index1];
k++;
index1++;
}
while (index2 <= end) {
arr[k] = tmp[index2];
k++;
index2++;
}
}
}
정답이다 ㅎㅎ