너굴 개발 일지

[Algorithm] 백준 10989. 수 정렬하기 3 (Java) 본문

혼자 공부,정리하는 알고리즘

[Algorithm] 백준 10989. 수 정렬하기 3 (Java)

너굴냥 2021. 10. 2. 23:15

[문제]

https://www.acmicpc.net/problem/10989

 

10989번: 수 정렬하기 3

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

www.acmicpc.net

[제출 답안]

첫번째로는 삽입 정렬을 사용하여 제출하였지만 시간 초과로 실패하였다... 자바 8 기준으로 시간은 3초, 메모리는 512MB의 제한이 있다.

import java.util.Scanner;

public class Main {
    public static void main(String[] args){
        Scanner s = new Scanner(System.in);
        int n = s.nextInt();

        int[] arr = new int[n];
        for(int i=0;i<n;i++){
            arr[i] = s.nextInt();
        }
        arr = func(arr, arr.length);

        for(int a : arr){
            System.out.println(a);
        }
    }

    public static int[] func(int[] arr, int size){
        for(int i=0;i<size;i++){
            int target = arr[i];
            int j = i=1;

            while(j>= 0 && target < arr[j]){
                arr[j+1] = arr[j];
                j--;
            }
            arr[j+1] = target;
        }
        return arr;
    }
}

두번째로는 Arrays 패키지의 sort()를 사용해 정렬을 하였다. 시간이 간당간당하게 3초를 초과하지 않았지만 시간복잡도에서 최악의 경우 O(n2) 로 좋지 않은 성능이 될 수도 있다.

package com.bjy.pracitce;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br =  new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();

        int n = Integer.parseInt(br.readLine());
        int[] arr = new int[n];

        for(int i=0;i<n;i++){
            arr[i] = Integer.parseInt(br.readLine());
        }

        Arrays.sort(arr);

        for(int i=0;i<n;i++){
            sb.append(arr[i]).append('\n');
        }
        System.out.println(sb);
    }
}

마지막으로 카운팅정렬을 사용하였다. 시간복잡도는 O(N + K) 인데 K는 자릿수를 의미하며 입력데이터가 K보다 훨씬 큰 경우, 즉 데이터가 많을수록 O(N) 에 가깝기 때문에 이상적으로는 O(N) 이라고 보아도 무방하다. 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        int[] cnt = new int[10001];

        BufferedReader br =  new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());

        for(int i=0;i<n;i++){
            cnt[Integer.parseInt(br.readLine())] ++;
        }

        br.close();
        StringBuilder sb = new StringBuilder();

        for(int i=1;i<10001;i++){
            while(cnt[i] >0 ){
                sb.append(i).append('\n');
                cnt[i]--;
            }
        }
        System.out.println(sb);
    }
}

[참고]

자바 카운팅 정렬

https://st-lab.tistory.com/104

 

자바 [JAVA] - 카운팅 정렬 (Counting Sort / 계수 정렬)

[정렬 알고리즘 모음] 더보기 1. 계수 정렬 (Counting Sort) - [현재 페이지] 2. 선택 정렬 (Selection Sort) 3. 삽입 정렬 (Insertion Sort) 4. 거품 정렬 (Bubble Sort) 5. 셸 정렬 (Shell Sort) 6. 힙 정렬 (H..

st-lab.tistory.com