알고리즘/프로그래머스 - JS

[프로그래머스-JS] level.1 완주하지 못한 선수

개발자성장기 2022. 6. 28. 20:04
반응형

 

 

 

나의코드 

처음에는  아래처럼 작성했다

 

function solution(participant, completion) {
    let fail = [];
    for(i=0; i<participant.length; i++){
        if(!completion.includes(participant[i])){
            fail.push(participant[i])
        }
        
    }
    
    return 1;
}

 

하지만 문제를 똑바로 읽지 않아서 중복일때 오류가 뜬다. 

그래서 다시 작성했다.

 

function solution(participant, completion) {
  
    for(i=0; i<completion.length; i++){
    const index = participant.indexOf(completion[i])
        participant.splice(index, 1)
    }
    const result = participant.join()
    return result;
}

이렇게 작성하니 테스트는 통과했지만 효율성에서 시간초과로 오답이 되었다. 

내가 볼땐 splice를 사용해서 그런 것 같다

배열을 뒤에서 부터 제거 할때는 상관없지만 맨앞이나 중간을 제거하면 시간이 많이 늘어나는 것으로 알고 있다.

 

그래서 다른 방법을 생각했다.

 

function solution(participant, completion) {
    let result
    const par = participant.reduce( (pre,cur) => {
        pre[cur] = (pre[cur] || 0) +1;
        return pre
    },{})
    
    const com = completion.reduce( (pre,cur) => {
        pre[cur] = (pre[cur] || 0) +1;
        return pre
    },{})
    
    for(i=0; i<participant.length; i++){
            if(com[participant[i]] !== par[participant[i]]){
                result = participant[i]
                break
            }
    }
    return result;
}

 

이렇게 하니 결국에는 통과했지만  그렇게 마음에 드는 코드는 아니였다. 

그래서 다른 분들의 코드를 보았다

 

 

 

다른 사람의 풀이 1

 

이 코드가 눈에 들어왔다. 

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 객체를 몰라서 공부하고 왔다. 

 

예시 테스트 케이스

participant completion return
["leo", "kiki", "eden"] ["eden", "kiki"] "leo"

 

 

해설

map.set(a ~    에서 처음에 맵 객체가 텅 비어있으니 map.get(a)는 undefine 이 나와서 0으로 되고 + 1 이 된다. 

즉  맵 객체안에 [["leo", 1]] 이 있는 상태가 된다.

 

그 다음

map.set(b~ 로 넘어가서 map.get(b) 는 map.get("eden") 이 되는데 맵 객체안에는 없으니  or 단계에서 0으로 선택이되고 -1 이 되어서

[["leo", 1], ["eden", -1]] 이 된다. 

 

그 다음

i = 1 이되고

다시 map.set(a~ 에서 map.get(a) 는 map.get("kiki")가 되고 이 역시 존재하지 않기에 0이 선택이되고 + 1 이된다

[["leo", 1], ["eden", -1], ["kiki", 1]  ]

 

그 다음

map.set(b~    map.get(b) 는 map.get("kiki")가 되고 이는 맵 객체에 존재하기에 value값을 가져온다음 -1 이되기에 0으로 된다.

[["leo", 1], ["eden", -1], ["kiki", 0]  ]

 

그 다음

i = 2 가 되고
다시 map.set(a~ 에서 map.get(a) 는 map.get("eden")가 되고 이는 맵 객체에 존대하기 때문에 value 값을 가져온다음 +1 이 되기에 0이 된다.

[["leo", 1], ["eden", 0], ["kiki", 0]  ]

 

그 다음

completion[2]가 존재하지 않는다

map.set(b~  b 자체가 존재하지도 않고 map.get(b) 는 map.get(undefined)가 되어서 아무 값도 없다. 

 

지금까지 맵 객체는 아래와 같다. 

[["leo", 1], ["eden", 0], ["kiki", 0]  ]

 

이걸 가지고 맵 객체는 순환 시켜주는 for of 문을 활용하면 된다.

for(let [k, v] of map) {
        if(v > 0) return k;
    }

이렇게 하면  "leo"만 출력이된다. 

 

여기서 보면 첫 번째  map.set의 역할은  참가자가   중복 참가(동명이인)를 했는지 안 했는지 판별하는 역할이다 

중복 참여했으면 2이상이되고 중복 참여를 하지 않았으면 1이된다. 

 

두 번째 map.set의 역할은 참가자중에서 완주자를 가려내는 역할은 한다. 

참가자가 완주를 했으면 -1을 해줌으로 0이되고  중복 참여(동명이인)를 했는데 그 중 일부만 완주하면 1이상이 된다. 

 

 

다른 사람의 풀이 2 

 

var solution=(_,$)=>_.find(_=>!$[_]--,$.map(_=>$[_]=($[_]|0)+1))

 

처음에 이거 보고 이게 뭔가 싶었다. 

 

 

반응형