알고리즘
[백준] 18870번 : 좌표 압축 _ JAVA ( 주석 설명 ) 본문
* 배운 점
입력된 값에 중복은 있으나 출력은 입력 수만큼 해야 한다는 생각에
'HashMap 은 key 중복이 안 되므로 사용하면 안된다' 고 넘겨짚었다. -> 'key value 를 상황에 따라 적절히 넣어주면 된다.'
문제를 풀면서 자료구조가 언제 어떻게 쓰이면 될 지 정확히 이해하고 넘어가도록 하자
1번 (시간초과)
→ 2번과 비슷하게 접근했으나,
HashMap 자료구조를 사용하지 않고 직접 중복된 값을 제거하는 과정 + list.indexof() 에서 시간초과가 났을 것으로 예상한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //빠른 입력을 위해 버퍼를 이용해 입력을 받는다.
int N = Integer.parseInt(br.readLine()); //수직선 위의 좌표의 개수를 입력받는다.
ArrayList<Integer> ary = new ArrayList<>(N); //좌표를 저장하기 위해 좌표의 개수만큼의 ArrayList 공간을 생성한다.
StringTokenizer st = new StringTokenizer(br.readLine());
for(int i=0;i<N;++i){
ary.add(Integer.parseInt(st.nextToken())); //수직선 위의 좌표를 입력받는다.
}
ArrayList<Integer> duplicate = (ArrayList<Integer>) ary.clone(); //정렬된 값에서, 정렬되기 전의 값들의 인덱스를 검색하기 위해 복사 배열을 만든다.
Collections.sort(duplicate); //복사된 배열을 정렬한다.
for(int i=0;i<duplicate.size()-1;++i){ //중복된 값은 제거해준다.
if(duplicate.get(i).equals(duplicate.get(i+1))){
duplicate.remove(i);
i--; //재차 검사를 위해 i--를 해준다.
}
}
StringBuilder sb = new StringBuilder();
for(int i=0; i<N;++i){
sb.append(duplicate.indexOf(ary.get(i))).append(' '); //정렬된 복제 ArrayList에서 처음 입력받은 ArrayList의 인덱스 값을 찾는다.
}
System.out.println(sb); //좌표 압축한 결과를 출력한다.
}
}
2번
→ 기존 입력받은 자료구조에서 규칙(순위)을 찾아 그에 맞게 정렬을 한 후,
중복을 제거하기 위해 HashMap 의 key - value 에 '정렬 값' - '순위' 를 저장한다.
그리고 기존에 입력받은 값들을 전체 한 번 순회하며 key 값과 매칭함으로써 원하는 값을 출력한다.
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)); //빠른 입력을 위해 버퍼를 이용해 입력을 받는다.
StringTokenizer st;
int N = Integer.parseInt(br.readLine()); //수직선 위의 좌표의 개수를 입력받는다.
ArrayList<Integer> list = new ArrayList<>(N); //좌표 수만큼의 ArrayList 공간을 생성한다.
st = new StringTokenizer(br.readLine());
for(int i=0;i<N;++i){ //입력받은 값을 ArrayList에 저장한다.
list.add(Integer.valueOf(st.nextToken()));
}
ArrayList<Integer> clone = (ArrayList<Integer>) list.clone(); //정렬 리스트를 따로 저장하기 위해 복사를 한다.
Collections.sort(clone); //오름차순으로 정렬한다.
HashMap<Integer,Integer> map = new HashMap(N); //정렬한 좌표를 중복 없이 저장하기 위해 HashMap 구조를 사용한다.
int rank = 0; //자신보다 작은 수가 몇 개 있는지
for(int i=0;i<clone.size();++i){
int input = clone.get(i); //정렬한 좌표에서 각 인덱스별로 추출하여 map 에 저장한다.
if(!map.containsKey(input)) { //key : 좌표값, value : 순위 을 넣는다. //containsValue 를 검사하는 이유는 중복된 수 index 를 계산하지 않기 위함이다.
map.put(input, rank);
rank++; //순위를 올린다.
}
}
StringBuilder sb = new StringBuilder();
for(int i=0;i<N;++i){
sb.append(map.get(list.get(i))).append(' '); //비정렬된(입력) 리스트 차례대로 값을 가지고 와 map - key 와 맞춰보며 순위를 찾는다.
}
System.out.println(sb); //순위를 출력한다.
}
}
'백준 - JAVA > 정렬' 카테고리의 다른 글
[백준] 10825번 국영수 _ JAVA ( 주석 설명 ) (0) | 2023.03.06 |
---|---|
[백준] 24060번 : 알고리즘 수업 - 병합 정렬 1 _ JAVA ( 주석 설명 ) (0) | 2023.02.13 |
[백준] 10814번 : 나이순 정렬 _ JAVA ( 주석 설명 ) (0) | 2023.02.10 |
[백준] 1181번 : 단어 정렬 _ JAVA ( 주석 설명 ) (0) | 2023.02.09 |
[백준] 11651번 : 좌표 정렬하기 2 _ JAVA ( 주석 설명 ) (0) | 2023.02.09 |