programmers
[Programmers Level 1 해시] 완주하지 못한 선수 Javascript
냠냠맨
2022. 12. 12. 12:59
⚡문제정보
한명 빼고 모두 완주한 마라톤 경기에서
완주를 못한 찐따 한명을 찾는 문제입니다.
동명이인이 있다는 조건이 있으니 단순하게 filter()를 이용해서 푸는 방법은 제한이 있을 것 같아요
항상 한명빼고 완주를 못하니까 두 배열을 비교해서 completion 배열에는 없는 한명을 찾아내면
되는 문제라고 생각했습니다.
🙄제한사항
마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.
completion의 길이는 participant의 길이보다 1 작습니다.
참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.
참가자 중에는 동명이인이 있을 수 있습니다.
🔍접근방법
없는 한명을 찾으면서 동명이인 케이스를 제거하기 위해 객체를 선언해주고
completion배열을 객체에 동명이인까지 고려해서 담아준 다음
participant와 비교해주면서 완주하지 못한 사람을 찾으려고했습니다.
🔍나의 풀이
function solution(participant, completion) {
function findrunner(part) {
let runner = new Object()
for(i=0; i< part.length ; i++) {
if(runner[part[i]] == undefined) {
runner[part[i]] = 1
}
else if (runner[part[i]] != undefined){
runner[part[i]]++
}
}
return runner
}
let problem = findrunner(participant)
for(i=0 ; i<completion.length ; i++) {
problem[completion[i]]--
}
return Object.entries(problem).sort((a,b) => b[1] - a[1])[0][0]
}
통과는 했습니다만
다른 사람들의 풀이를 보니 효율적으로 풀지 못했다는 생각이 들었습니다.
sort()를 사용하지않고도 풀 수 있을텐데라는 생각도 들고
Map을 사용해서 풀걸하는 생각이 드네요
코드 해석은 다음과 같습니다.
function solution(participant, completion) {
//participant를 객체로 바꿔줄 함수를 만들기
function findrunner(part) {
let runner = new Object()
for(i=0; i< part.length ; i++) {
if(runner[part[i]] == undefined) {
runner[part[i]] = 1
}
//만약 처음 만나는 키라면 1을 할당해줌
else if (runner[part[i]] != undefined){
runner[part[i]]++
}
//중복키라면 ++, if()는 생략해도 무방함
}
return runner
}
let problem = findrunner(participant)
// 함수에 participant를 넣은 결과를 담은 변수 선언
for(i=0 ; i<completion.length ; i++) {
problem[completion[i]]--
//completion의 모든 키를 순회하면서 빼주면 value값이 1인 값 한개와
//value가 0으로 구성된 나머지 값들이 만들어짐
}
return Object.entries(problem).sort((a,b) => b[1] - a[1])[0][0]
//밸류값을 기준으로 내림차순 정렬해주면 맨앞에 있는 값이 완주못한사람
}
🔍다른사람의 풀이
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';
}
Map 자료구조를 이용한 풀이입니다.
set을 이용하면 map에 키와 값을 할당시켜줄 수 있는데
만약 a가 값이 있다면 ++ 해주고 값이 없다면 or연산자로 0을 넣어준다음 +1을 해주는 식인가보네요
Map을 열심히 공부해놓고 익숙하지않다고 안 쓴 과거를 반성합니다
function solution(participant, completion) {
var dic = completion.reduce((obj, t)=> (obj[t]= obj[t] ? obj[t]+1 : 1 , obj) ,{});
return participant.find(t=> {
if(dic[t])
dic[t] = dic[t]-1;
else
return true;
});
}
reduce와 find를 이용한 풀이입니다.
잘 이해가 안가는데 obj[t] ?만 해도 어떻게 저 삼항연산자가 돌아가는지..?
🔍쪼끔 더 개선한 나의 풀이
function solution(participant, completion) {
let map = new Map()
for(i=0 ; i<participant.length; i++) {
map.set(participant[i], map.get(participant[i]) + 1 || 0 +1 )
/* 맵자료구조는 .set() 을 통해 키밸류 값을 집어넣을 수 있음
set(키, 밸류)을 설정하는 형태
get은 맵자료구조.get(키) 의 형태로 사용하고 return값은 키의 밸류값임
다만 맵자료구조에서 정의되지않은 키값의 밸류는 항상 undefined임
따라서 위의 경우 || 단축평가를 통해 앞의 값이 falsy값(undefined,null,0,false 등등)이면 뒤의 값을 반환하게해서
한번도 등장한적 없는 키라면 밸류를 0+1해주고
등장한적있는 키라면 get(키) +1을 해주는 식으로 코드를 짰음
읽기 쉽게 하기위해 0 + 1을 해줬지만 그냥 value를 1로 지정해도 무방함
만약 위 코드를 if문 형태로 구현한다면 다음과 같을것임
if(map.get(participant[i]) != undefined) {
map.set(participant[i], map.get(participant) +1)
}
else {
map.set(participant[i] , 1)
}
*/
}
for(i=0 ; i<completion.length; i++) {
map.set(completion[i], map.get(completion[i]) - 1)
/* 위코드와 마찬가지로 set과 get을 사용해서
밸류값을 -해줌 이 과정을 끝까지 반복하면 밸류가 1인 키가 단 하나 존재하게될것임
*/
}
return [...map].filter(ele => ele[1] != 0)[0][0]
/* map 자료구조를 전개연산자를 이용해 map 자료구조를 2차원 배열 형태로 바꿔준뒤
배열 메서드 filter를 통해 밸류값이 0인 경우를 모두 지워줌
그결과 filter까지 거친 경우 값은
[[키값,1]]의 형태가 될것임 우리가 원하는 리턴값은 완주하지못한선수의 이름이니까
[0][0]을 통해 키값에 접근해서 리턴해줌
*/
}
반응형