문제
https://www.acmicpc.net/problem/18870
18870번: 좌표 압축
수직선 위에 N개의 좌표 X1, X2, ..., XN이 있다. 이 좌표에 좌표 압축을 적용하려고 한다. Xi를 좌표 압축한 결과 X'i의 값은 Xi > Xj를 만족하는 서로 다른 좌표의 개수와 같아야 한다. X1, X2, ..., XN에 좌
www.acmicpc.net
풀이
1. HashMap을 이용하여 풀 경우
원본 배열에 대해서 정렬한다.
정렬한 배열에 hashMap에 추가하면서 value를 증가시킨다. 이때 기존의 HashMap에 key 값이 있는지 확인하고 없을 경우에만 value를 증가시킨다.
(문제 예시를 예로들어 보자면, arr = {2, 4, -10, 4, -9} 를 정렬하면 {-10, -9, 2, 4, 4} 가 된다.
이 정렬된 배열에 대해 hashMap에 추가하면서 value를 증가시킨다.
예를 들어 가장 낮은 값인 -10이 0이 될 것이다. 그 다음 -9가 1 .. 이런식으로 말이다. )
2. 이분탐색을 이용하여 풀 경우
원본 배열에 대해 정렬한다.
정렬한 배열에서 중복을 제거한다.
중복 제거한 배열에 대해 이분탐색을 진행하여 index를 구한다.
두 경우다 주의해야 할것은 출력은 StringBuilder로 해야 시간 초과가 안난다는 점이다.
코드
1. HashMap
import java.util.*;
import java.io.*;
public class Main {
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
StringBuilder sb = new StringBuilder();
int n = Integer.parseInt(br.readLine());
int arr [] = new int [n];
int sorted [] = new int [n];
HashMap<Integer, Integer> map = new HashMap<>();
st = new StringTokenizer(br.readLine());
for(int i=0;i<n;i++) {
arr[i] = Integer.parseInt(st.nextToken());
sorted[i] = arr[i];
}
Arrays.sort(sorted);
int idx = 0;
for(int i=0;i<n;i++) {
if(!map.containsKey(sorted[i]))
map.put(sorted[i], idx++);
}
for(int i=0;i<n;i++) {
sb.append(map.get(arr[i]) + " ");
}
System.out.print(sb);
}
}
2. 이분탐색
import java.util.*;
import java.io.*;
public class Main {
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
StringBuilder sb = new StringBuilder();
int n = Integer.parseInt(br.readLine());
st = new StringTokenizer(br.readLine());
int arr [] = new int [n];
int temp [] = new int [n];
for(int i=0;i<n;i++) {
arr[i] = Integer.parseInt(st.nextToken());
temp[i] = arr[i];
}
Arrays.sort(temp);
ArrayList<Integer> list = new ArrayList<>();
list.add(temp[0]);
for(int i=1;i<n;i++) {
if(temp[i-1] != temp[i]) {
list.add(temp[i]);
}
}
for(int i = 0; i < n; i++) {
sb.append(binarySearch(arr[i], list)+" ");
}
System.out.print(sb);
}
static int binarySearch(int val, ArrayList<Integer> list) {
int s = 0;
int e = list.size() - 1;
while(s <= e) {
int mid = (s + e) / 2;
if(list.get(mid) < val) {
s = mid+1;
}
else if(list.get(mid) > val) {
e = mid-1;
}
else {
return mid;
}
}
return -1;
}
}
문제
https://www.acmicpc.net/problem/18870
18870번: 좌표 압축
수직선 위에 N개의 좌표 X1, X2, ..., XN이 있다. 이 좌표에 좌표 압축을 적용하려고 한다. Xi를 좌표 압축한 결과 X'i의 값은 Xi > Xj를 만족하는 서로 다른 좌표의 개수와 같아야 한다. X1, X2, ..., XN에 좌
www.acmicpc.net
풀이
1. HashMap을 이용하여 풀 경우
원본 배열에 대해서 정렬한다.
정렬한 배열에 hashMap에 추가하면서 value를 증가시킨다. 이때 기존의 HashMap에 key 값이 있는지 확인하고 없을 경우에만 value를 증가시킨다.
(문제 예시를 예로들어 보자면, arr = {2, 4, -10, 4, -9} 를 정렬하면 {-10, -9, 2, 4, 4} 가 된다.
이 정렬된 배열에 대해 hashMap에 추가하면서 value를 증가시킨다.
예를 들어 가장 낮은 값인 -10이 0이 될 것이다. 그 다음 -9가 1 .. 이런식으로 말이다. )
2. 이분탐색을 이용하여 풀 경우
원본 배열에 대해 정렬한다.
정렬한 배열에서 중복을 제거한다.
중복 제거한 배열에 대해 이분탐색을 진행하여 index를 구한다.
두 경우다 주의해야 할것은 출력은 StringBuilder로 해야 시간 초과가 안난다는 점이다.
코드
1. HashMap
import java.util.*; import java.io.*; public class Main { public static void main(String args[]) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st; StringBuilder sb = new StringBuilder(); int n = Integer.parseInt(br.readLine()); int arr [] = new int [n]; int sorted [] = new int [n]; HashMap<Integer, Integer> map = new HashMap<>(); st = new StringTokenizer(br.readLine()); for(int i=0;i<n;i++) { arr[i] = Integer.parseInt(st.nextToken()); sorted[i] = arr[i]; } Arrays.sort(sorted); int idx = 0; for(int i=0;i<n;i++) { if(!map.containsKey(sorted[i])) map.put(sorted[i], idx++); } for(int i=0;i<n;i++) { sb.append(map.get(arr[i]) + " "); } System.out.print(sb); } }
2. 이분탐색
import java.util.*; import java.io.*; public class Main { public static void main(String args[]) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st; StringBuilder sb = new StringBuilder(); int n = Integer.parseInt(br.readLine()); st = new StringTokenizer(br.readLine()); int arr [] = new int [n]; int temp [] = new int [n]; for(int i=0;i<n;i++) { arr[i] = Integer.parseInt(st.nextToken()); temp[i] = arr[i]; } Arrays.sort(temp); ArrayList<Integer> list = new ArrayList<>(); list.add(temp[0]); for(int i=1;i<n;i++) { if(temp[i-1] != temp[i]) { list.add(temp[i]); } } for(int i = 0; i < n; i++) { sb.append(binarySearch(arr[i], list)+" "); } System.out.print(sb); } static int binarySearch(int val, ArrayList<Integer> list) { int s = 0; int e = list.size() - 1; while(s <= e) { int mid = (s + e) / 2; if(list.get(mid) < val) { s = mid+1; } else if(list.get(mid) > val) { e = mid-1; } else { return mid; } } return -1; } }