Algorithm/개념 & 문법
[Algorithm] 선택 정렬
ajeong7038
2024. 2. 27. 10:49
`이것이 코딩 테스트다 (나동빈)` 커리큘럼에 따라 진행합니다
✨ 정렬
정의
- 데이터를 특정한 기준에 따라 순서대로 나열하는 것
- 일반적으로 문제 상황에 따라 적절한 정렬 알고리즘이 공식처럼 사용된다
✨ 선택 정렬
정의
- 처리되지 않은 데이터 중에서 가장 작은 데이터를 선택해 맨 앞에 있는 데이터와 바꾸는 것을 반복하는 정렬
- 이중 반복문을 사용해 가장 작은 원소 확인 -> 데이터 교환의 과정을 반복한다
시간 복잡도
- N번 만큼 가장 작은 수를 찾아 맨 앞으로 보내야 하므로 O(N^2) 만큼의 시간이 소요된다
- N + (N-1) + (N-2) + ... + 2 => (N^2 + N - 2) / 2
✨ 문제
- 선택 정렬을 사용하지 않지만...
접근
- 좌표 Xi보다 작은 값이 몇 개 있는지 구하기
1차 시도
- HashSet으로 중복 값 제거 + 오름차순으로 만들어준 후 인덱스 값을 가져오려고 했다
- 그러나 좌표 압축 부분에서 시간 초과로 실패. 나머지는 O(N)의 시간 복잡도를 유지한 반면, 좌표 압축 부분에서 이중 for문으로 O(N^2)의 시간 복잡도를...
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
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];
StringTokenizer st = new StringTokenizer(br.readLine());
// 배열에 넣기
for (int i=0; i<N; i++) {
arr[i]= Integer.parseInt(st.nextToken());
}
HashSet<Integer> hashSet = new HashSet<>();
for (int i : arr) {
hashSet.add(i);
}
System.out.println(hashSet);
// 정렬
ArrayList<Integer> arrayList = new ArrayList<>(hashSet);
Collections.sort(arrayList);
// 좌표 압축
for (int i=0; i<N; i++) {
for (int j=0; j<arrayList.size(); j++) {
if (arr[i] == arrayList.get(j)) {
sb.append(j).append(" ");
}
}
}
System.out.println(sb);
}
}
2차 시도
- 좌표 압축 부분에서 문제가 있다는 사실을 깨닫고 다른 분들의 코드를 참고하던 중, HashSet에는 get()이 없어 HashMap을 쓰는게 더 낫다는 것을 깨달았다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
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];
int[] sortedArr = new int[N];
StringTokenizer st = new StringTokenizer(br.readLine());
// 배열에 넣기
for (int i=0; i<N; i++) {
arr[i] = sortedArr[i] = Integer.parseInt(st.nextToken());
}
// 배열 정렬
Arrays.sort(sortedArr);
HashMap<Integer, Integer> hashMap = new HashMap<>();
int index = 0;
for (int i : sortedArr) {
// 중복 값 제거
if (!hashMap.containsKey(i)) {
hashMap.put(i, index);
index++;
}
}
for (int k : arr) {
int idx = hashMap.get(k); // 원본 배열 원소(key)에 대한 인덱스 값(value)을 가져온다
sb.append(idx).append(" ");
}
System.out.println(sb);
}
}
성공!