Algorithm/Java
[백준/JAVA] 1620번: 나는야 포켓몬 마스터 이다솜
dbfl9911
2024. 10. 22. 16:05
반응형
https://www.acmicpc.net/problem/1620
[ 오답 노트 ]
❌ 기존 오답 코드
// https://www.acmicpc.net/problem/1620
package Data_Structure2.나는야포켓몬마스터이다솜;
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken()); // 26
int M = Integer.parseInt(st.nextToken()); // 5
StringBuilder sb = new StringBuilder();
HashMap<Integer, String> hm = new HashMap<>();
for(int i = 1; i <= N; i++) {
hm.put(i, br.readLine());
}
for(int j = 0; j < M; j++) {
for(int i : hm.keySet()) {
// 문자열이라면 숫자로
if(br.readLine().equals(hm.get(i))) {
sb.append(i).append('\n');
}else { // 숫자라면 문자열로
sb.append(hm.get(i)).append('\n');
}
}
}
System.out.println(sb);
}
}
📌 기존 코드의 문제점
- 중복 반복 : 문제의 개수(M)만큼의 반복문 안에서, hm.keySet()을 다시 반복하며 모든 키 값을 탐색하여 매번 if-else 조건을 확인합니다. 이는 매우 비효율적이며 N과 M의 값이 커질수록 속도가 급격히 느려집니다.
- 단일 HashMap만 사용: 포켓몬 번호로 이름을 찾기 위한 HashMap만 사용하여, 문자열(포켓몬 이름)으로 번호를 찾기 위한 과정이 어렵고 비효율적입니다. 문자열로 번호를 찾아야 할 때 hm.keySet()을 전부 탐색하여야 하기 때문입니다.
- 비효율적인 조건 검사: br.readLine().equals(hm.get(i)) 방식은 매번 모든 keySet()을 탐색해야 하므로 효율이 떨어집니다. 단일 HashMap으로 두 가지 방식의 검색을 동시에 지원하기가 어렵습니다.
[ 정답 코드 & 올바른 풀이 ]
📌 정답 코드
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken()); // 26
int M = Integer.parseInt(st.nextToken()); // 5
StringBuilder sb = new StringBuilder();
// 번호 -> 이름
HashMap<Integer, String> hm1 = new HashMap<>();
// 이름 -> 번호
HashMap<String, Integer> hm2 = new HashMap<>();
for(int i = 1; i <= N; i++) {
String s = br.readLine();
hm1.put(i, s);
hm2.put(s, i);
}
for(int j = 0; j < M; j++) {
String s = br.readLine();
// 첫문자가 숫자라면
if(Character.isDigit(s.charAt(0))) {
// 문자열 출력
sb.append(hm1.get(Integer.parseInt(s))).append('\n');
} // 첫문자가 문자라면
else{
// 숫자 출력
sb.append(hm2.get(s)).append('\n');
}
}
System.out.println(sb);
}
}
📌 개선된 접근 방법
- 두 개의 HashMap 사용:
- hm1은 번호로 이름을 찾을 때 사용하고, hm2는 이름으로 번호를 찾을 때 사용하여 각각 최적화된 구조로 접근합니다.
- 각각의 HashMap에 O(1)의 시간 복잡도로 접근 가능해 문제를 빠르게 해결할 수 있습니다.
- 조건문 최적화:
- 문자열이 숫자인지 문자인지 확인할 때 Character.isDigit() 메서드를 사용
- s의 첫 번째 문자가 숫자인 경우 Character.isDigit(s.charAt(0))를 통해 쉽게 확인
- StringBuilder 사용으로 출력 최적화:
- 모든 결과값을 StringBuilder에 추가한 후 한 번에 출력하여 성능을 향상시켰습니다. 이는 많은 입력과 출력을 다룰 때 효과적입니다.
반응형