-
[백준/JAVA] 1620번: 나는야 포켓몬 마스터 이다솜Algorithm 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에 추가한 후 한 번에 출력하여 성능을 향상시켰습니다. 이는 많은 입력과 출력을 다룰 때 효과적입니다.
'Algorithm' 카테고리의 다른 글
[백준/JAVA] 2075번 : N번째 큰 수 (0) 2024.10.22 [백준/JAVA] 4358번 : 생태학 (0) 2024.10.22 [백준/JAVA] 2493번: 탑 (0) 2024.10.19 [백준/JAVA] 괄호의 값 (0) 2024.10.19 [백준/JAVA] 쇠막대기 (0) 2024.10.19