[프로그래머스] 완주하지 못한 선수
[프로그래머스] 완주하지 못한 선수
▪︎ 문제
▪︎ 알고리즘 설계
- Sorting / Loop 활용
- 두 배열을 정렬한다.
- completion list의 length 만큼 돌면서 participant에만 존재하는 한 명을 찾는다.
- 배열을 전부 다 뒤져도 답이 없다면, participant의 마지막 주자가 완주하지 못한 선수이다.
- Hash 활용
- key에 선수 이름, value에 count를 갖는 해시 맵을 만든다.
- completion에 존재하는 선수들의 해시를 뺀다.
- value가 남아있는 선수가 완주하지 못한 선수이다.
▪︎ 코드
Sorting / Loop 활용
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
import java.util.*; class Solution { public String solution(String[] participant, String[] completion) { Arrays.sort(participant); Arrays.sort(completion); int i = 0; for(; i < participant.length - 1; i++) { if(!(participant[i].equals(completion[i]))) { break; } } return participant[i]; } }
Hash 활용1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
import java.util.*; class Solution { public String solution(String[] participant, String[] completion) { String answer = ""; HashMap<String, Integer> map = new HashMap<>(); for(String player : participant) map.put(player, map.getOrDefault(player, 0) + 1); for(String player : completion) map.put(player, map.get(player) - 1); for(String key : map.keySet()) { // map이 가지고 있는 key들을 하나의 배열로 담아 하나씩 꺼낼 수 있음 if(map.get(key) != 0) { answer = key; break; } } return answer; } }
Hash 활용2
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
import java.util.*; class Solution { public String solution(String[] participant, String[] completion) { String answer = ""; HashMap<String, Integer> map = new HashMap<>(); for(String player : participant) map.put(player, map.getOrDefault(player, 0) + 1); for(String player : completion) map.put(player, map.get(player) - 1); // 반복을 쉽게해주는 하나의 클래스 Iterator(Map.Entry<String, Integer>> iter = map.entrySet().iterator(); while(iter.hasNext()) { // 여러 개의 객체들이 다음 객체가 있는 지를 확인 Map.Entry<String, Integer> entry = iter.next(); // 다음 객체 entry 저장 if(entry.getValue() != 0) { // 해당 entry의 value가 0이 아니라면 answer = entry.getKey(); // 해당 key를 답에 저장 break; } } return answer; } }
▪︎ 시간복잡도
- Sorting / Loop 활용:
O(N log N)
- Hash 활용:
O(N)
▪︎ 틀린 이유
- 문자열 비교 시
==
사용- Java에서
==
는 문자열의 참조값을 비교하므로, 문자열 값 자체를 비교하는equals()
를 사용해야 한다.
- Java에서
- 이중 반복문 사용
- 불필요한 이중 루프를 사용하면 시간복잡도가
O(N²)
로 증가하여 비효율적이다.
- 불필요한 이중 루프를 사용하면 시간복잡도가
- 마지막 주자 고려 누락
- 완주자 배열의 길이는 참가자보다 항상 1 작으므로, 루프에서 차이가 없을 때 마지막 참가자를 반환해야 한다.
- 동명이인 처리 실패
- 단순히 이름이 같은 경우 한 번만 삭제하는 방식은 동명이인을 제대로 처리하지 못한다.
- 따라서 각 이름의 등장 횟수를 관리할 수 있는 해시맵 또는 정렬 비교가 필요하다.
- 정렬 및 해시맵 사용 발상 부족
- 문제의 특성상 정렬 또는 해시맵을 이용하면 동명이인과 빠른 탐색 문제를 모두 해결할 수 있다.
- 정렬 방식: 정렬 후 같은 이름이 연속해서 나오므로 순서대로 비교하면 됨.
- 해시맵 방식: 동일한 이름이 등장할 때마다 카운트를 증가시켜 정확한 횟수를 관리할 수 있음
- 문제의 특성상 정렬 또는 해시맵을 이용하면 동명이인과 빠른 탐색 문제를 모두 해결할 수 있다.
▪︎ 느낀점 / 기억할 정보
- 중복이 존재하는 데이터는
HashMap
을 사용하여 key에 이름, value에 등장 횟수를 저장하고 관리하는 아이디어 생각할 수 있어야 한다. - Java에서
==
는 참조 비교,equals()
는 값 비교이다. - Iterator와 Map.Entry 사용법 숙지
- 해시맵의 keySet()을 순회하거나 entrySet()을 순회하면서 value 조건으로 값을 찾을 수 있다.
This post is licensed under CC BY 4.0 by the author.