ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준/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);
        }
    }

    📌 기존 코드의 문제점

    1. 중복 반복 : 문제의 개수(M)만큼의 반복문 안에서, hm.keySet()을 다시 반복하며 모든 키 값을 탐색하여 매번 if-else 조건을 확인합니다. 이는 매우 비효율적이며 N과 M의 값이 커질수록 속도가 급격히 느려집니다.
    2. 단일 HashMap만 사용: 포켓몬 번호로 이름을 찾기 위한 HashMap만 사용하여, 문자열(포켓몬 이름)으로 번호를 찾기 위한 과정이 어렵고 비효율적입니다. 문자열로 번호를 찾아야 할 때 hm.keySet()을 전부 탐색하여야 하기 때문입니다.
    3. 비효율적인 조건 검사: 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);
        }
    }

     

     

    📌 개선된 접근 방법

    1. 두 개의 HashMap 사용:
      • hm1은 번호로 이름을 찾을 때 사용하고, hm2는 이름으로 번호를 찾을 때 사용하여 각각 최적화된 구조로 접근합니다.
      • 각각의 HashMap에 O(1)의 시간 복잡도로 접근 가능해 문제를 빠르게 해결할 수 있습니다.
    2. 조건문 최적화:
      • 문자열이 숫자인지 문자인지 확인할 때 Character.isDigit() 메서드를 사용
      • s의 첫 번째 문자가 숫자인 경우 Character.isDigit(s.charAt(0))를 통해 쉽게 확인
    3. 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
Designed by Tistory.