[백준] 2751: 수 정렬하기2

김태하·2023년 2월 24일
1
post-thumbnail

문제


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

입력


첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 수가 주어진다. 이 수는 절댓값이 1,000,000보다 작거나 같은 정수이다. 수는 중복되지 않는다.

출력


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

코드

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

public class _2751 {
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt();
		StringBuilder sb = new StringBuilder();
		ArrayList<Integer> list = new ArrayList<Integer>();
		
		for(int i=0; i<N; i++) {
			list.add(sc.nextInt());
		}
		Collections.sort(list);
		for(int num : list)
			sb.append(num).append('\n');
		System.out.println(sb);

	}
}

풀이


문제의 설명을 보면

시간 복잡도가 O(nlogn)인 정렬 알고리즘으로 풀 수 있습니다. 예를 들면 병합 정렬, 힙 정렬 등이 있지만, 어려운 알고리즘이므로 지금은 언어에 내장된 정렬 함수를 쓰는 것을 추천드립니다.

라고 되어 있다.
처음에는 내장된 함수가 아닌 자체적으로 sort라는 함수를 작성하여 heap 정렬을 구현해 제출을 해보았다. 시간 초과라는 결과가 나와 내장 함수에 대해 알아보았다.

1. Arrays.sort()

  • Arrays.sort()는 int,char 같은 primitive type 배열에서 정렬을 지원
  • Arrays.sort() 의 경우 dual-pivot Quicksort 알고리즘을 사용
  • 문제 설명에서 얘기한 바와 같이 평균 시간복잡도가 O(nlogn) 이다.
    하지만 최악의 경우 시간복잡도는 O(n2)이기 때문에 이 문제에서는 사용하지 못하게 된다.

그렇다면 어떤 내장 함수를 사용하여야 할까? 🧐

2. Collections.sort()

  • Collections.sort() 은 Timsort인데 이와 같은 경우 합병 및 삽입정렬 알고리즘을 사용한다.
  • 두 가지가 섞여있는 정렬 알고리즘을 hybrid sorting algorithm 이라고 하는데, 두 정렬 모두 안정 정렬(stable sort)이기 때문에 Timsort를 hybrid stable sorting algorithm이라고도 한다.
  • 시간복잡도는 O(n) ~ O(nlogn) 을 보장한다.
  • Collections.sort()를 사용할 때에는 primitive 배열이 아닌 List 계열(ArrayList, LinkedList 등..)의 자료구조를 사용하여 정렬하여야 한다.

하지만 여기서 문제가 생겼다. Collections.sort()를 사용해도 시간초과가 발생하였다. 그 이유를 알아보니 Scanner를 사용할 경우 BufferedWriterStringBuilder를 사용해야 한다는 점이다. 필자는 StringBuilder를 사용하였다.

  1. Collections.sort()는 List계열의 자료구조를 사용하여야 하므로 ArrayList를 사용하여 list 변수를 만들어준다.
  2. list에 Scanner를 이용해 숫자를 입력받는다.
  3. Collections.sort(list)를 사용하여 리스트를 정렬한다.
  4. StringBuilder 형식의 sb에 각 리스트의 숫자들을 줄바꿈 문자를 붙여 넣어준다.
  5. 이를 바로 출력한다.

참고 링크 : https://st-lab.tistory.com/106
문제 링크 : 2751번 수 정렬하기2

0개의 댓글