2 minute read




문제 풀이


이번 문제는 입력받은 포켓문 문자열과 포켓몬 번호가 쌍으로 존재해야 한다.
여기선 HashMap을 활용하면 포켓몬 이름과 번호를 쉽게 쌍으로 연결지어 만들 수 있다.


아이디어 도출

  • 시간제한은 2초, N의 범위는 최대 10만개, M의 범위도 최대 10만개로 이중 for문을 사용할 경우 시간제한이 발생할 가능성이 높다.
  • N개의 포켓몬 문자열을 입력받으며 포켓몬 이름 문자열과 해당 인덱스를 번호로 하여 HashMap에 저장한다.
  • M개의 입력받은 포켓몬 문자열이 포켓몬 이름(문자열)인지 번호(인덱스)인지 확인한다.
    • 만약 문자열이라면, 이름이기에 번호를 출력한다.(HashMap의 key에 대응하는 value 값)
    • 만약 번호라면, 번호이기에 이름을 출력한다.(이름을 인덱스 순으로 가지고 있는 String 배열의 인덱스에 대응하는 문자열 값)


그렇다면 아이디어대로 코드를 작성해보자.

1
2
3
4
5
6
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());

HashMap<String, Integer> hm = new HashMap<>();
String[] arr = new String[N+1];

먼저 N과 M을 입력받고 포켓몬이름, 포켓몬번호를 쌍으로 담을 HashMap과 포켓몬이름을 인덱스 순으로 저장할 String 배열을 하나 생성하자.

String 배열을 별도로 만드는 이유는?
HashMap에서는 key값에 대응하는 value 값을 찾을 수 있는 get() 메서드가 있지만 key()을 찾으려면 keySet(), entrySet() 등 반복문을 한 번 돌려야지만 찾을 수 있기 때문에 String 배열에 인덱스 순으로 이름을 저장해두고 있다면 HashMap을 순회하며 key값을 찾을 필요없이 배열의 인덱스로 접근하여 가져오면 되기 때문이다.

1
2
3
4
5
for(int i=1; i<=N; i++) {
    String poketmon = br.readLine();
    hm.put(poketmon, i);
    arr[i] = poketmon;
}

다음으로 N개의 포켓몬 이름을 입력받으며 HashMap에 key를 포켓몬 이름(문자열)으로, value를 포켓몬 번호(int형 인덱스)로 저장한다.
그리고 인덱스 순으로 이름을 arr 배열에 함께 저장한다.

1
2
3
4
5
for(int i=0; i<M; i++) {
    String s = br.readLine();
    if(hm.containsKey(s)) bw.write(hm.get(s) + "\n");
    else bw.write(arr[Integer.parseInt(s)] + "\n");
}

마지막으로 M개의 문자열을 입력받으며 먼저 입력값이 포켓몬 이름인지 포켓몬 번호인지를 구분한다.

  1. 만약 포켓몬 이름이라면, 포켓몬 번호를 출력하면 된다.
  2. 만약 포켓몬 번호라면, 해당 번호가 인덱스이기에 위에서 포켓몬 이름을 인덱스 순으로 저장해둔 arr 배열에 인덱스로 주어 접근하면 인덱스에 해당하는 포켓몬 이름값을 가져올 수 있다.



작성코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.io.*;
import java.util.*;

class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        StringTokenizer st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());

        HashMap<String, Integer> hm = new HashMap<>();
        String[] arr = new String[N+1];

        for(int i=1; i<=N; i++) {
            String poketmon = br.readLine();
            hm.put(poketmon, i);
            arr[i] = poketmon;
        }

        for(int i=0; i<M; i++) {
            String s = br.readLine();
            if(hm.containsKey(s)) bw.write(hm.get(s) + "\n");
            else bw.write(arr[Integer.parseInt(s)] + "\n");
        }

        bw.flush();
        bw.close();
        br.close();
    }   
}

회고

  • HashMap에서 value값을 get() 메서드로 찾는 것은 쉽지만 key값을 추가적인 반복문 없이 대응되는 문자열 배열만을 활용하여 찾을 수 있었다.