[JS] 해시 > 완주하지 못한 선수
수많은 마라톤 선수들이 마라톤에 참여하였습니다.
단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.
마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.
function solution(participant, completion) {
participant = participant.sort();
completion = completion.sort();
for (let i = 0; i < completion.length; i++) {
if (participant[i] !== completion[i])
return participant[i];
}
return participant[participant.length - 1];
}
이번 테스트의 핵심은 해시였지만 해시를 쓰지 않고 문제를 풀었다..ㅠ
처음 생각했을 때 단순히 두 배열의 값 중 일치하지 않는 값을 찾으면 되겠다는 생각으로 먼저 두 배열을 정렬했다.
그 다음 반복문을 돌리고 참여선수 배열 값과 완주선수 배열 값이 일치하지 않으면 그 값을 리턴했다.
[ 'eden', 'kiki', 'leo' ] [ 'eden', 'kiki' ] 같은 경우 for문으로는 찾을 수 없기 때문에 가장 마지막 인덱스의 값을 리턴하는 식으로 따로 리턴값을 줬다.
function solution(participant, completion) {
const map = new Map();
for(let i = 0; i < participant.length; i++) {
let a = participant[i],
b = completion[i];
map.set(a, (map.get(a) || 0) + 1);
map.set(b, (map.get(b) || 0) - 1);
}
for(let [k, v] of map) {
if(v > 0) return k;
}
return 'nothing';
}
해시를 사용한 코드
1. new Map()으로 map 변수를 생성한다.
2. 참여선수배열(participant)을 반복한다.
3. 반복문 안에서 0번째 인덱스 값부터 변수 a와 b에 저장하고 set으로 map에 값을 저장한다.
4. a와 b는 map의 키가 되고, 밸류에서 map.get(a) 또는 map.get(b)로 동명이인이 있으면 그 값을, 없을 경우 0을 넣는다.
5. for of로 map을 반복하며 밸류가 0보다 크다면 완주하지 못한 선수이므로 그 값인 key를 리턴한다.
위의 코드처럼 로그를 찍었을 때 참여 선수인 leo는 map.get('leo')로 했을 때 값이 없었기 때문에 0+1이 되어 map에 {'leo' => 1}로 저장이 된다.
완주 선수인 eden도 get했을 때 값이 없었기 때문에 0-1이 되어 map은 Map { 'leo' => 1, 'eden' => -1 }가 된다.
1번 인덱스로 이동해서 kiki는 참여선수로는 값이 처음 들어가서 0+1이 되어 kiki => 1이 된다.
하지만 완주선수에서 map.get('kiki')를 하면 값이 이미 들어가 있어서 기존 밸류인 1-1이 되어 kiki => 0이 된다.
2번 인덱스에서 eden도 마찬가지다.
이미 0번 인덱스 때 eden으로 키가 저장되어 있기 때문에 eden은 기존 값인 -1에 +1이 되어 eden => 0이 된다.
참여선수와 완주선수 배열의 길이는 1씩 차이가 나기 때문에 undefined가 발생하는 부분은 무시한다.
따라서 참여는 하되 완주는 하지 못해 밸류가 0이 아닌 사람은 'leo'임을 알 수 있다!
