1. ๋ฌธ์ ์ค๋ช
2. ์ ๊ทผ ๋ฐฉ์
๊ธฐ์ ์ ๋ ฌ
์ ์ด์ฉํด์ ๋ฌธ์ ๋ฅผ ํ๋ ค๊ณ ํ๋ค. ๊ทผ๋ฐ, ๋ค๋ฅธ ์ฌ๋๋ค์ ์ง๋ฌธ์ ๋ณด๋, ์์ ์๋ ๊ธฐ์ ์ ๋ ฌ์ ์ด์ฉํด ๋ฌธ์ ๊ฐ ํ๋ ธ์ผ๋, ๋ฉ๋ชจ๋ฆฌ ์ ํ์ด ์๊ธด ์ดํ๋ก ํ๋ฆฌ์ง ์๋๋ค๊ณ ํ๋ค. ๋ฌธ์ ์์ ์ฃผ์ด์ง๋ ๋ฐ์ดํฐ์ ํฌ๊ธฐ๋ 10,000,000 ๊ฐ์ด๊ณ , ํ๋์ ๋ฐ์ดํฐ๋ฅผ int ๋ฐฐ์ด์ ์์๋ก ๋ฃ์ด์ ๋ณด๊ดํ๋ค๋ฉด, ์ด 40MB๊ฐ ๋ ๋ค. (๋ฐ์ ๋ณด๋ฉด, java์ ๊ฒฝ์ฐ 512MB๊น์ง ์ฉ๋ ํ์ฉ๋๋ค๊ณ ์ ํ์๋๋ฐ, ๋๊ฐ์ด ์๋๋ค.)
๊ธฐ์ ์ ๋ ฌ์ ๊ณต๊ฐ ๋ณต์ก๋๋ O(W+n)์ผ๋ก 40MB์ ๊ฒฝ์ฐ ๋ฌธ์ ์์ ์ฃผ๋ ๋ฉ๋ชจ๋ฆฌ ์ฉ๋์ ์ด๊ณผํ๋ค. ๋ด๊ฐ ArrayDeque 10๊ฐ๋ฅผ ํ์ฉํด ๊ธฐ์ ์ ๋ ฌ์ ๊ตฌํํ๋ ๋ฐ๋์ ์ค๋ฅ๊ฐ ๋ฌ๋ ์ถ์ด์, ์ฝ๋ฉ ํ
์คํธ ์ฑ
์ ์๋ ํ์ด๋ฅผ ๋๊ฐ์ด ๊ตฌํํ์์ผ๋, ๊ทธ๊ฑด ๋ ์๊ฐ์ด๊ณผ๊ฐ ๋ฌ๋ค.
ํ์ง๋ง ๊ทธ๋ฅ ๊ธฐ์์ ๋ ฌ๋ก ๋ฌธ์ ๋ฅผ ํ์ด๋ณด๊ฒ ๋ค. ์ฌ๊ธฐ ์๋๋ฉด ์จ๋ณผ ์ผ์ด ์์ ๊ฒ ๊ฐ๋ค. ๊ธฐ์์ ๋ ฌ์ ์ต์
์ ์๊ฐ๋ณต์ก๋๊ฐ O(kn) (k๋ ์
๋ ฅ๊ฐ ์ต๋ ์๋ฆฟ์)
์ผ๋ก ์ง๊ธ๊น์ง ๋ฐฐ์ด ์ ๋ ฌ ์ค์์ ๊ฐ์ฅ ๋น ๋ฅด์ง๋ง, 10๊ฐ์ Queue ํน์ ๊ทธ์ ์์ํ๋ bucket ๋ฐฐ์ด์ ๋ฐ๋ก ๋์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ฉ๋ชจ๋ฆฌ ์๋ชจ๊ฐ ์์ฒญ๋ ์๊ณ ๋ฆฌ์ฆ
์ด๋ค.
ํด๋น ๋ฌธ์ ์์๋ ๋ฉ๋ชจ๋ฆฌ ํ์ฉ๋์ด 8MB ์ด์ง๋ง, ๋ง์ฝ์ Bucket ๋ฐฐ์ด์ int ๋ฐฐ์ด๋ก ๋ง๋ค ๊ฒฝ์ฐ, ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ผ์ผํ ์ ์ฅํ๊ธฐ๋ง ํด๋ 40MB๊ฐ ๋ ๋ค.
๋ํ ๋ฐ์ดํฐ์ ์/์ ๊ฐ์ ์๊ด์์ด ์ธ ์ ์์๋ ํ ์ ๋ ฌ์ ๋นํด ๊ธฐ์ ์ ๋ ฌ์ ์์ ์ ์๋ ์์ ์ ์ ๋ผ๋ฆฌ, ์์ ์ ์๋ ์์ ์ ์๋ผ๋ฆฌ ๋ฐ๋ก ์ ๋ ฌํด์ ๊ฐ์ ๊ตฌํด์ผํ๋ ๋ฐฉ์
์ด๋ค.
๋ฑ๊ฐ๊ตํ์ ๋ฒ์น์ ๋ฐ๋ผ ์๋๋ ๋น ๋ฅด์ง๋ง, ์กฐ๊ฑด์ด ๊น๋ค๋กญ๊ณ , ๋ค๋ฅธ ์ ๋ ฌ์ ๋นํด ๊ณต๊ฐ๋ณต์ก๋๊ฐ ๋ง์ด ๋ค์ด์ ์ฝํ ์์ ์์ฃผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์๋๊ฑฐ ๊ฐ๋ค. ํ์ง๋ง ๋ง์ฝ์ ์ฝํ ์์ ๋ฉ๋ชจ๋ฆฌ ์ ํ์ด 512MB ์ด์์ผ๋ก ์ฌ์ ๋กญ๊ณ , ๋ฐ์ดํฐ์ ํฌ๊ธฐ๊ฐ 10^7 ์ ๋๋ผ๋ฉด ์ฌ์ฉํด๋ณผ๋ง ํ ๊ฒ ๊ฐ๋ค.
์ ๊ทผ ๋ฐฉ์
(1) String.charAt์ผ๋ก ํ์ฌ ์๋ฆฟ์์ ๊ฐ์ ํน์ ํ๋ค. ๋ง์ฝ ์ฐ๋ฆฌ๊ฐ 10000์ ์๋ฆฟ์๋ฅผ ๋ณด๊ณ ์๋๋ฐ, ์ซ์๊ฐ 12๋ก 10์ ์๋ฆฌ๊น์ง ๋ฐ์ ์๋ค๋ฉด 0์ผ๋ก ํน์ ๋๋๋ก ํ๋ค.
(2) ํ์ฌ ์๋ฆฟ์์ ๊ฐ์ ํด๋นํ๋ ArrayDeque์ ๊ฐ์ ์ง์ด๋ฃ๋๋ค.
(3) 0๋ฒ Deque๋ถํฐ 9๋ฒ Deque๊น์ง ์ฐจ๋ก๋๋ก ์๋์ ๋ฐฐ์ด์ ๊ฐ์ ์ง์ด๋ฃ๋๋ค.
(4) ํด๋น ํ์๋ฅผ ์ ๋ ฅ๊ฐ ์ค ์ต๋ ์๋ฆฟ์ ๊ฐ์ ๋งํผ ๋ฐ๋ณตํ๋ค. (ex- ์๋ฆฟ์์ ๊ฐ์๊ฐ 5๊ฐ๋ฉด 5๋ฒ ๋ฐ๋ณต)
3. ์ฝ๋ ๋ถ์
import java.io.*;
import java.util.ArrayDeque;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int max = 0;
int N = Integer.parseInt(br.readLine());
int [] arr = new int [N];
ArrayDeque<Integer> [] aqs = new ArrayDeque[10];
for (int i = 0; i < 10; i++) {
aqs[i] = new ArrayDeque<>();
}
for (int i = 0; i < N; i++) {
arr[i] = Integer.parseInt(br.readLine());
max = Math.max(max, arr[i]);
}
int max_length = String.valueOf(max).length();
int digit = 1;
while (digit <= max_length){
// ๊ฐ ์ง์ด๋ฃ๊ธฐ
for (int i = 0; i < N; i++) {
String now = String.valueOf(arr[i]);
if(now.length()>=digit) aqs[Character.getNumericValue(now.charAt(now.length()-digit))].add(Integer.parseInt(now));
else aqs[0].add(Integer.parseInt(now));
}
// ๊ฐ ์ฌ์ ๋ ฌํด์ arr๋ก ๋ฃ๊ธฐ
int aqs_idx = 0;
int arr_idx = 0;
while (aqs_idx <= 9){
while (!aqs[aqs_idx].isEmpty()){
arr[arr_idx++] = aqs[aqs_idx].poll();
}
aqs_idx++;
}
digit++;
}
// ์ถ๋ ฅ
for (int ans : arr){
System.out.println(ans);
}
}
}
4. ์ฑ์ฅํ๊ธฐ
์์์๋ ๊ธฐ์ ์ ๋ ฌ์ ์ด๋ก ๊ทธ๋๋ก Queue๋ฅผ 10๊ฐ ๊ตฌํํด์ ๋ฌธ์ ๋ฅผ ํ์๋๋ฐ, ๋ฐฐ์ด์ ์ด์ฉํด, Queue ์ ์ธ์ ๋๋ ๋ถํ์ํ ์๊ฐ ์๋ชจ๋ฅผ ์ค์ด๋ ๋ฐฉ๋ฒ๋ ์์ด, ํด๋น ๋ฐฉ๋ฒ์ ๊ณต๋ถ ํ์ ๊ธฐ์ ํ๋ค.
bucket์ด๋ ๋ฐฐ์ด์ ๋ง๋ค์ด ํด๋น ๋ฐฐ์ด์ ๋์ ํฉ ๋ฐฐ์ด๋ก ์ฌ์ฉํ์ฌ ๋ฌธ์ ๋ฅผ ํผ๋ค.
์ฒซ ๋ฒ์งธ ๊ณ์ฐ
bucket ๋ฐฐ์ด์ index๋ 10๊ฐ์ queue์ฒ๋ผ ์๋ฆฟ์์ ๊ฐ์ ์๋ฏธํ๋ค. value๋ ํด๋น ์๋ฆฟ์์ ๊ฐ์ ๊ฐ์ง ์์์ ๊ฐ์์ด๋ค.
(ex- ๋ง์ฝ ํ์ฌ ๊ณ์ฐํ๋ ์๊ฐ 12345์ด๊ณ ๋ณด๋ ์๋ฆฟ์๊ฐ 10์ด๋ผ๋ฉด, bucket[4]++์ ํด์ค์ผ ํ๋ค.)๋ ๋ฒ์งธ ๊ณ์ฐ
๋์ ํฉ์ ํตํด, ๋ณธ ๋ฐฐ์ด์ ํด๋น ๊ฐ๋ค์ด ๋ค์ด๊ฐ ์์น๋ฅผ ๊ตฌํ๋ค. ์๋ฅผ ๋ค์ด
์ฒซ ๋ฒ์งธ ๊ณ์ฐ์ผ๋ก ๋ง๋ค์ด์ง bucket ๋ฐฐ์ด์ด ๋ค์๊ณผ ๊ฐ๋ค๊ณ ํ์.1 2 3 4 5 1 1 0 2 1 ํ์ฌ 10์ ์๋ฆฟ์๋ฅผ ๋ณด๊ณ ์๋ค๊ณ ํ ๋ ์ด๊ฒ์ ๋ป์ 10์ ์๋ฆฟ์๊ฐ 1์ธ ๊ฐ์ด 1๊ฐ, 2์ธ ๊ฐ์ด 1๊ฐ, 4์ธ ๊ฐ์ด 2๊ฐ, 5์ธ ๊ฐ์ด 1๊ฐ์ด๋ค.
์ด๋ฅผ ๋์ ํฉ์ ๋ฐ๊ฟ๋ณด์1 2 3 4 5 1 2 2 4 5 ์ด์ ํด๋น ๊ฐ์ ์๋ฏธ๋ ๋ค์๊ณผ ๊ฐ๋ค. index 5์ value == 5 ์ธ๋ฐ, 10์ ์๋ฆฟ์๊ฐ 5์ธ ๊ฐ์ ๋ณธ ๋ฐฐ์ด arr ์ ์์น๋ arr[5]๋ผ๋ ๊ฒ์ด๋ค.
10์ ์๋ฆฟ์๊ฐ 4์ธ ๊ฐ์ด 2๊ฐ ์์๋๋ฐ, ์ด๊ฑด ์ด๋ป๊ฒ ํ๋์?
arr[4]์ ๊ฐ์ ์ง์ด๋ฃ์ ๋ค์ bucket[4]-- ํด์ ์ธ๋ฑ์ค๋ฅผ ํ ์นธ ์ค์ธ๋ค.
๐น๏ธ์ซ์์ ํน์ ์๋ฆฟ์์ ํด๋นํ๋ ๊ฐ์ ๊ตฌํ๋ ๋ฐฉ๋ฒ ๐น๏ธ
int n = 12345;
int digit = 100; // ๊ตฌํ๋ ค๋ ํน์ ์๋ฆฟ์
System.out.println((n/digit)%10);
/*
1. n/digit์ผ๋ก ์๋ณธ ๊ฐ์์ ์ํ๋ ์๋ฆฟ์ ์ดํ์ ๊ฐ๋ค์ ๋ชจ๋ ์๋ผ๋ธ๋ค.
(์ด๋ ๊ฒ ๋๋ฉด ๊ตฌํ๊ณ ์ ํ๋ ์๋ฆฟ์์ ๊ฐ์ด 1์ ์๋ฆฟ์๊ฐ ๋ ๊ฒ์ด๋ค.)
2. %10 ๊ณ์ฐ์ผ๋ก ๊ตฌํ๊ณ ์ ํ๋ ๊ฐ๋ง ๋ฐ๋ก ๋ผ์ด๋ธ๋ค.
*/
์ ์ฒด ์ฝ๋
import java.io.*;
import java.util.ArrayDeque;
import java.util.StringTokenizer;
public class Main {
public static int[] A;
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());
A = new int[N];
for(int i = 0; i < N; i++){
A[i] = Integer.parseInt(br.readLine());
}
br.close();
Radix_Sort(A, 5);
for(int i = 0; i < N; i++){
bw.write(A[i] + "\n");
}
bw.flush();
bw.close();
}
public static void Radix_Sort(int[] A, int max_size){
int [] output = new int [A.length];
int cnt = 0;
int digit = 1;
while (cnt <= max_size){
// bucket์ ๋์ ํฉ ๋ฐฐ์ด์ด ๋๊ธฐ ์ ๊น์ง๋ index = ์๋ฆฟ์, value = ํด๋น ์๋ฆฟ์์ ๊ฐ์ ๊ฐ์ ์ด๋ค.
// ์๋ฅผ ๋ค์ด bucket[4]๋ ํ์ฌ ์๋ฆฟ์ = 4์ธ ๊ฐ์ ๊ฐ์์ด๋ค.
// ๋์ ํฉ์ด ๋๋ฉด, bucket์ index๋ ๊ทธ index์ ํด๋นํ๋ ์๋ฆฟ์๋ฅผ ๊ฐ์ง ๊ฐ์ด ๋ณธ ๋ฐฐ์ด A์ ์ ์ฅ๋ ๋ ์์น์ด๋ค.
// ์๋ฅผ ๋ค์ด bucket[4] = 4 ์ด๊ณ ์๋ฆฟ์๋ 10์ด๋ผ๊ณ ํด๋ณด์ . ๊ทธ๋ฌ๋ฉด 12345๋ผ๋ ์ซ์๋ ๋ณธ ๋ฐฐ์ด 4๋ฒ์งธ ์๋ฆฌ์ ์ ์ฅ๋๋ค.
// ๋ง์ฝ 2345๋ผ๋ ์ซ์๊ฐ ํ๋ ๋ ์์ด์ ์๋ฆฟ์๊ฐ ๊ฒน์น๋ ๊ฒฝ์ฐ๋ ์ด๋ป๊ฒ ํ ๊น ์ด ๊ฒฝ์ฐ bucket[4]๋ ์๊น 4๋ฒ์จฐ ์๋ฆฌ์ ๊ฐ ํ๋๋ฅผ
// ์ ์ฅ ํ์์ผ๋ก, 3์ด ๋ ๊ฒ์ด๊ณ 2345๋ ๋ณธ ๋ฐฐ์ด A์ 3๋ฒ์จฐ ์๋ฆฌ์ ์ ์ฅ๋๋ค.
int [] bucket = new int [10];
for (int i = 0; i < A.length; i++) {
bucket[(A[i]/digit)%10]++;
}
// ๋์ ํฉ์ผ๋ก ๋ง๋ค๊ธฐ
for (int i = 1; i < 10; i++) {
bucket[i] += bucket[i-1];
}
for (int i = A.length-1; i >= 0; i--) {
output[bucket[(A[i]/digit)%10]-1] = A[i];
bucket[(A[i]/digit%10)]--; // -> ๋ณด๋ฉด ๋ฐฐ์ด์ ๋ค์์๋ทฐํ ์ฑ์ฐ๊ณ ์๋ค.
// -> ๋ฐ๋ผ์ ๋์ค์ 10000์ผ๋ก ๋๋์์ ์ ๋ง์ ์๋ค์ด 0์ ์ ์ฅ๋์ด ์์ํ
๋ฐ,
// ํฐ ์ธ๋ฑ์ค๋ฅผ ์์ ๊ฐ๋ถํฐ ์ฑ์ฐ๋ฉด ๋ด๋ฆผ์ฐจ์์ด ๋ ์ ๋ฐ์ ์๋ค.
}
for (int i = 0; i < A.length; i++) {
A[i] = output[i];
}
digit *= 10;
cnt++;
}
}
}