문제 및 입출력
이름이 중복되지 않고 현재 어떤 상태를 저장해야 하는 전형적인 Hashmap 문제이다
ArrayList<String> result = new ArrayList<>();
for (String s : log.keySet()) {
if (log.get(s).equals("enter")) {
result.add(s);
}
}
Collections.sort(result, Collections.reverseOrder());
리스트에 enter 상태인 사람을 담고 역순으로 정렬하여 출력하면 된다.
이 과정이 번거롭기도 하고 더 좋은 풀이가 있을거라 믿고 다른분들의 코드를 찾아봤는데,
if (log.containsKey(name)) m.remove(name);
else m.put(name, log);
ArrayList<String> list = new ArrayList<String>(m.keySet());
위와 같이 해시맵에 이름이 이미 있으면 삭제를 하는 방법이 있다.
이렇게 하면 굳이 출근인지 퇴근인지 상태를 저장할 필요가 없고, 더 나아가서 HashSet 으로도 변경이 가능할 것 같다
String name = st.nextToken();
if (log.contains(name)) log.remove(name);
else log.add(name);
각 코드에 대한 성능은 아래 풀이 후기에서 !
public class Main {
public static void main(String[] args) throws IOException {
HashSet<String> log = new HashSet<>();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
StringTokenizer st;
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
String name = st.nextToken();
if (log.contains(name)) log.remove(name);
else log.add(name);
}
ArrayList<String> result = new ArrayList<>(log);
Collections.sort(result, Collections.reverseOrder());
for (String s : result) {
System.out.println(s);
}
}
}
역시 HashSet을 사용할때가 메모리와 시간 단축이 가장 좋은것을 확인할 수 있다
근데 이 문제를 접하는 대부분의 사람들은 (나포함) 당연히 HashMap을 처음에 떠올릴 것 같고, 출퇴근을 판단하는 로직도 대부분 state를 비교했을것이라 생각한다
근데 풀이를 서치하여 보니 아니였음 똑똑한 사람들 많다
구현을 이미 잘 한다면 이런 부분에서 실력차이가 나는 것 아닐까...
아 추가로
ArrayList<String> result = new ArrayList<>(log);
이렇게 String 값을 한 번에 리스트로 바꾸는 컬렉션 타입 변환을 쉽게 할 수 있는것을 처음 알게 되었다