완주하지 못한 선수
문제 설명
수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.
마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.
제한사항
- 마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.
- completion의 길이는 participant의 길이보다 1 작습니다.
- 참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.
- 참가자 중에는 동명이인이 있을 수 있습니다.
입출력 예
participantcompletionreturn
[leo, kiki, eden] | [eden, kiki] | leo |
[marina, josipa, nikola, vinko, filipa] | [josipa, filipa, marina, nikola] | vinko |
[mislav, stanko, mislav, ana] | [stanko, ana, mislav] | mislav |
입출력 예 설명
예제 #1
leo는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.
예제 #2
vinko는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.
예제 #3
mislav는 참여자 명단에는 두 명이 있지만, 완주자 명단에는 한 명밖에 없기 때문에 한명은 완주하지 못했습니다.
실패한 풀이
function solution(participant, completion) {
completion.forEach(element => {
participant.splice(participant.indexOf(element),1);
});
return participant[0];
}
나름대로 간결하게 구현하려고 노력했다.
하지만 성능에서 전부 불합격으로 충격받고 한참을 고민하다 풀이를 찾아보았다.
splice가 시간복잡도를 많이 사용하며, for문이 끝까지 돌아가야하기 때문에 성능이 불합격이다.
올바른 풀이1
function solution(participant, completion) {
participant.sort();
completion.sort();
for(var i=0;i<participant.length;i++){
if(participant[i] !== completion[i]){
return participant[i];
}
}
}
어이없도록 간단하다.
두 배열을 sort후 for문으로 순차적으로 비교하고, false면 곧바로 for문을 종료 시킨다.
올바른 풀이2
해시 카테고리에 있는 문제이므로 해시를 이용해 해결해보자.
해시는 쉽게 Map, object를 의미한다.
function solution(participant, completion) {
const myMap = new Map();
for ( const participant of participants){
if(!myMap.get(participant)){
myMap.set(participant, 1);
}else{
myMap.set(participant, myMap.get(participant)+1);
}
}
for(const completion of completions){
if(myMap.get(completion)){
myMap.set(completion, myMap.get(completion)-1);
}
}
for(const participant of participants){
if(myMap.get(participant) && myMap.get(participant) >=1 ){
answer = participant;
}
}
}
function solution(participant, completion) {
let hashed = []
participant.forEach(entry => {
hashed[entry] = hashed[entry] ? hashed[entry] + 1 : 1
})
completion.forEach(entry => {
hashed[entry] = hashed[entry] - 1
})
for (var key in hashed) {
if (hashed[key] >= 1) return key
}
}
두 가지 모두 동일한 풀이이다.
key로 이름을, value로 참가 인원수를 저장한다.
그리고, 완주자 배열을 반복시켜 value를 1씩 감소시킨다.
value가 1 이상이면 완주하지 못한 인원이므로 return 한다.
함수 정리
number array.indexOf(찾을 요소)
배열에서 요소를 탐색하고 index를 반환한다.
없다면 -1을 반환한다.
var array.find(array => array.name == 찾을 요소)
배열에서 요소를 탐색하고 요소를 반환한다.
인수로 callback를 필요로 한다.
해당되는 값이 없다면 undefine이 반환된다.
number array.findIndex(array => array.name == 찾을요소)
find와 동일하지만 요소의 index를 반환한다.
myMap = new Map()
myMap.set(key, value)
myMap.get(key)
object와 흡사한 개념으로 set, get을 이용해야 요소를 참조할 수 있다.
사용은 간단하며, get 사용시 요소가 없다면 false가 반환된다.
for(var i in array)
for(var element of array)
Js에서는 for(int i=0; i<arrary.length; i++)을 이와같이 간단하게 작성할 수 있다.
in은 index, of는 요소 그 자체이다. forEach와 동일하다고 할 수 있다.
hashed[entry] = hashed[entry] ? hashed[entry] + 1 : 1
데이터가 true면 앞쪽을, false면 뒤쪽을 반환한다.
'Programming > Algorithm' 카테고리의 다른 글
[JS/알고리즘] 스택/큐 : 다리를 지나는 트럭 (프로그래머스) (0) | 2021.02.06 |
---|---|
[JS/알고리즘] 해쉬 : 베스트앨범 (프로그래머스) (1) | 2021.02.03 |
[JS/알고리즘] 스킬트리 (프로그래머스) (0) | 2021.01.31 |
[JS/알고리즘] 스택/큐 : 기능개발 (프로그래머스) (0) | 2021.01.31 |
[JS/알고리즘] 해시 : 위장 (프로그래머스) (0) | 2021.01.31 |