[Problem] 숫자 정렬
빠르고 간단한 숫자 정렬 방법
문제
입력값은 다음과 같습니다.
\[N \; a_1 \; a_2 \; a_3 \; ... \; a_N\]
여기서 N은 정렬해야 할 숫자의 개수이고, 뒤에 나온 N개의 숫자들은 오름차순으로 정렬해야 할 숫자들입니다.
이때 N개의 숫자들은 중복이 없고, \(-1000000 \le a_i \le 1000000\) 의 범위를 갖습니다.
예를 들어 입력값이
5 5 1 3 2 4
라고 한다면 출력값은 12345가 되야 합니다.
어떤 정렬 알고리즘도 사용하지 않는다!
정렬해야 할 숫자의 범위가 음수도 있으므로,
음수용 배열, 양수용 배열 을 만들어줍니다.
int[] negative = new int[1000001];
int[] positive = new int[1000001];
-1000000이나 1000000까지 저장하려면 배열의 크기를 1000001로 만들어야합니다.
정렬해야할 숫자를 순서대로 읽습니다.
만약 입력값이
3 2 0 -5
라고 하면 정렬해야 할 숫자는 2, 0, -5가 되고, 이를 순서대로 읽습니다.
현재 배열을 만들기만 했으므로, 모든 배열의 요소들의 값은 0입니다.
먼저 2를 읽고 양수이므로 positive[2]++ 로 저장합니다.
다음 0을 읽고 양수(음수가 아니면 양수로 간주)므로 positive[0]++ 로 저장합니다.
다음 -5를 읽고 음수므로 negative[-1*-5]++ 로 저장합니다.
이제 배열을 읽고 순서대로 출력만 하면 됩니다.
먼저 음수가 더 작으므로 negative 부터 읽습니다.
다만 negative는 negative[1000000]부터 시작해서 negative[1]까지 읽어야합니다.
뒤에 있는 요소일수록 더 작을 것이기 때문입니다.
for(int i=1000000; i>0; i--){
if(negative[i] > 0) System.out.print(-1*i);
}
다음 양수도 같은 방식으로 읽는데, positive는
positive[0]부터 시작해서 positive[1000000]까지 읽습니다.
앞에 있는 요소일수록 더 작을 것이기 때문입니다.
for(int i=0; i<1000001; i++){
if(positive[i] > 0) System.out.print(i);
}
응용
문제에서는 정렬해야할 숫자가 중복이 없다고 했지만,
만약에 중복된 숫자도 나온다면?
그땐 출력을 조금만 바꿔주면 됩니다.
예를 들어서 negative를 출력한다면
for(int i=1000000; i>0; i--){
for(int j=0; j<negative[i]){
System.out.print(-1*i);
}
}
코드
import java.util.Scanner;
public class P2751_2 {
public static void main(String[] ar){
Scanner sc = new Scanner(System.in);
int count = sc.nextInt();
int[] negative = new int[1000001];
int[] positive = new int[1000001];
for(int i=0; i<count; i++){
int temp = sc.nextInt();
if(temp<0) negative[-1*temp] = temp;
else positive[temp] = 1;
}
StringBuilder sb = new StringBuilder();
for(int i=1000000; i>0; i--){
if(negative[i]<0) sb.append(negative[i]+"\n");
}
for(int i=0; i<1000001; i++){
if(positive[i]>0) sb.append(i+"\n");
}
System.out.print(sb);
}
}
일단 정렬해야할 숫자가 중복이 없는 문제이기 때문에
positive[i]++ 대신 positive[i]=1 이라고 썻습니다.
큰 상관 없습니다.
또한 자바에선 System.out.print()가 속도가 느리므로 for문마다 쓰면 속도가 느려집니다.
그래서 StringBuilder 객체를 만들어서
거기다 출력할 숫자를 다 저장하고 한번에 출력하고 있습니다.
그걸 제외하곤 위의 설명과 같습니다.
솔직한 생각
개발 경험이 적어서 그런지 모르겠지만, 이런 코드를 처음 봤습니다.
처음 딱 봤을 때 느낌은…
‘레알 양아치처럼 풀었다…’
‘잔머리 보소…’
물론 정렬해야할 숫자의 양이 적고, 숫자의 크기 범위만 클 때는
쓸데없는 메모리 낭비일수도 있지만… 문제 풀때는 꽤 좋은 방법인거 같습니다.
속도도 빠르고…