코딩테스트

최빈값 구하기__ 정답 풀이

GABOJOK 2023. 9. 21. 01:28

레벨 0 문제였다. 

그렇지만 오늘의 나는 혼자서 풀지 못했다..😂

 

이 문제를 씹어먹겠다는 ㅋㅋㅋㅋ 강한 의지로 답안을 하나하나 뜯어보았다😼

 

간단히 말하면 문제는 배열에 들어있는 값들 중 가장 많이 나온 값을 리턴하면 되고, 

가장 많이 나온 값이 한개가 아닐 경우 -1을 리턴하면 되었다. 

 

이 문제를 뜯어보려고 다른 사람들의 풀이를 살펴보다 보니 정말 풀이 방법이 다 달랐다. .

이제까지 내가 풀었던 문제 대부분은 풀이 유형이 3가지 정도로 정리되었다.

그만큼 배울게 많은 문제였다 😃😆

 

처음에 나는 빈 obj 설정후, 반복문으로 풀려고 했다. ㅋㅋㅋㅋ

그런데 4시간을 붇잡아도 계속 정답률이 100%가 나오지 않았다...

 

 

일단 정답을 살펴보자.

1. 

function solution(array) {
    let arr = new Map();
    
    for(let i=0; i<array.length; i++){
        arr.set(array[i], (arr.get(array[i]) || 0)+1); 
    }

    let max = Math.max(...[...arr].map((a)=>{return a[1]}))
    let count = [...arr].filter((a)=>{return a[1] ===max}).length  
    
    if(count >1){ 
        return -1 
    }else{  
        return [...arr].find((v) => {return v[1] === max})[0];
    };
}

solution([1,2,3,3,3,4])

 

 

좀더 하나하나 뜯어보자.

function solution(array) {
    //생성자 함수를 이용해서 Map 자료를 arr라는 변수에 담아두었다.
    let arr = new Map();
    
    //반복문을 이용해서 arr라는 Map 자료형에 요소들을 집어넣었다.
    for(let i=0; i<array.length; i++){
    	//arr.set(키 , 값)  이렇게 하면 키와 값이 들어간다. (Map 자료형은 obj와 다름)
        arr.set(array[i], (arr.get(array[i]) || 0)+1); 
        
        //그런데 값을 넣는 공간에 or연산자가 들어가 있다. 
        //array[i]를 키로 가지고 있는 값을 불러오는데, 만약 그것이 없다면 undefined 일 것이다.
        //undefined인 경우 false에 해당하고, or 연산자는 모두가 false 이면 마지막 값을 반환한다. 
        //그럼 아직 값이 할당되지 않은 경우, (arr.get(array[i]) || 0)는 0이고, 
        //+1을 하기때문에 1이 할당된다.
    }
    
    //arr에는 이렇게 담겨있다.
    //Map(4) {1 => 1, 2 => 1, 3 => 3, 5 => 1}
    
    
    let max = Math.max(...[...arr].map((a)=>{return a[1]}))
    
    //[...arr] 이 말은 Map 자료가 담겨있는 arr를 spread operator를 이용해서 풀어서 배열로 담아준다. 
    //[[1, 1],[2, 1],[3, 3],[4, 1]]]
    //그리고 이 자료를 반복하면서 작은 배열 하나하나의 [1]번째 값을 return 한다. 
    //[...arr].map((a)=>{return a[1]} 의 값은 [1,1,3,1] 이 나온다.
    //Math.max()함수는 괄호 안에 있는 값들 중에서 최댓값을 반환하는데, 배열의 상태로는 넣을 수 없다. 
    //그래서 또 한번 spread operator를 사용해서 Math.max함수에 넣어준다.
    //이렇게 max에는 arr 값의 최대값이 담겼다. 
    
    
    let count = [...arr].filter((a)=>{return a[1] ===max}).length
    
    //[[1, 1],[2, 1],[3, 3],[4, 1]]]이걸 filter 해서 새로운 배열을 내주겠다는 말이다. 
    //조건으로 배열의 요소인 작은배열에 1번째 요소가 max와 같은 경우만 리턴하고,
    //그것의 길이를 count에 넣어준다. 
    // 즉 가장 큰값이 1개라면 1을 넣어주고, 2개라면 2를 넣어준다.
   
    
    if(count >1){         //만약 count가 여러개라면,
        return -1 
    }else{                //count가 1개라면,
        return [...arr].find((v) => {return v[1] === max})[0];
        	//[[1, 1],[2, 1],[3, 3],[4, 1]]]여기서 조건에 해당하는걸 찾는다. 
            // 작은배열의 1번째 요소가 max와 같은 작은 배열만 찾아서,
            // 그것의 0번쨰 요소를 리턴한다.
    };
}

solution([1,2,3,3,3,4])

 

 

 

 

정답2.

function solution(array) {
    const obj = {};
    let val = 0;
    let key = 0;
    
    for(let e of array){
        obj[e]===undefined? obj[e] = 1 : obj[e]++
        
        if(obj[e]>val){
            val = obj[e];
            key = e;
        }else if(obj[e] === val && e!==key ){
            key = -1;
        }
    }
    return key;
}

solution([1,2,3,3,3,4])

 

뜯어보기

function solution(array) {
    const obj = {};
    let val = 0;
    let key = 0;
    
	//이터러블 객체인 array는 for of 반복문이 가능하다. 
    for(let e of array){
    	//obj에 num키에 값이 아직 할당되지 않았을 경우. obj에 num이라는 키를 주고, 그 값을 1로 할당.
        //그게 아니라면, 즉 이미 num키에 값이 할당되어 있다면 값을 1씩 증가시킬것.
        obj[e]===undefined? obj[e] = 1 : obj[e]++
        
        // 만약 obj[num]의 값이 maxCount 보다 클 경우 maxCount에 obj[num]을 재할당. 즉 몇개 있는지.
        // 그리고 mostFrequent 에는 키를 넣어준다. 즉 어떤 숫자인지 넣어줌.
        if(obj[e]>val){
            val = obj[e];   //1  1  3
            key = e;        //1  2  3
        }else if(obj[e] === val && e!==key ){
        	//만약 obj[num]의 값이 이미 있는 최댓값과 같고, 해당 키가 이미 샌 키가 아니라면, -1을 할당함.
            key = -1;
        }
    }
    return key;

}

solution([1,2,3,3,3,4])

 

 

정답3.

function solution(array) {
    let m = new Map();
    for (let n of array) m.set(n, (m.get(n) || 0)+1);
    //m을 출력하면, {1 => 1},{2 => 1},{3 => 3},{4 => 1}
    
    //1번 과정과 여기가 다른데, sort는 오름차순 혹은 내림차순 정렬을 해주는 함수이고, 
    //spread operator를 이용해 배열로 만든 m을 하나하나 꺼낸것. 
    //즉 작은배열a[1,1] 과 또다른 작은배열b[2,1] 을 가지고, 
    //각각의 작은배열의 1번째 요소의 값을 비교해서 내림차순으로 정렬. 
    
    m = [...m].sort((a,b)=>b[1]-a[1]);
    //m을 출력하면 [3, 3], [1, 1], [2, 1], [4, 1]
    
    //or연산자와(둘중 하나라도 true 라면 true 반환.), 3항연산자를 이용했다.
    //m의 길이가 1과 같거나, "m의 0번째 요소의 1번째 요소"가 "1번째 요소의 1번째 요소"보다 크다면
    //즉 m이 한개 있거나, 최빈값이 1개라면 내림차순 정렬한 m의 0번째 요소의 0번째 요소를 가져와줘. 즉 키를 가져와줘.
    //그게 아니라 m의 길이가 1보다 큰데, 최빈값이 여러개라면 -1 리턴
    return m.length === 1 || m[0][1] > m[1][1] ? m[0][0] : -1;
}

solution([1,2,3,3,3,4])

 

 

정답4.

const solution = (array) => {
    const counter = array.reduce((acc, cur) => ({
        ...acc,
        [cur]: (acc[cur] || 0) + 1
    }), {})

    const items = Object.keys(counter).map((key) => [
        Number(key), counter[key]
    ]).sort((a, b) => b[1] - a[1])

    if (items[0][1] === items?.[1]?.[1]) {
        return -1
    }

    return items[0][0];
}

solution([1,2,3,3,3,4])

 

뜯어보기 

const solution = (array) => {
    const counter = array.reduce((acc, cur) => ({
        ...acc,
        [cur]: (acc[cur] || 0) + 1
    }), {})

    const items = Object.keys(counter).map((key) => [
        Number(key), counter[key]
    ]).sort((a, b) => b[1] - a[1])

    if (items[0][1] === items?.[1]?.[1]) {
        return -1
    }

    return items[0][0];
}

solution([1,2,3,3,3,4])

 

 

 

정답 5.

function solution(array) {

    let setArr = [...new Set(array)];

    let calArr = setArr.map((v,i) => array.filter(dv => dv == v).length);

    let rsltArr = calArr.map((mv,mi) => { if(mv == Math.max(...calArr)) return mi; return -1}).filter(v => v != -1)

    return rsltArr.length > 1 ? -1 : setArr[rsltArr[0]];
}

solution([1,2,3,3,3,4])

 

정답 6.

function solution(array) {
  const counts = array.reduce((a, c) => (a[c] ? { ...a, [c]: a[c] + 1 } : { ...a, [c]: 1 }), {});
  const max = Math.max(...Object.values(counts));
  const modes = Object.keys(counts).filter(key => counts[key] === max);
  return modes.length === 1 ? +modes[0] : -1;
}

solution([1,2,3,3,3,4])

 

  • Map 자료형을 활용하는 방법도 있다. 
  • 콜백 함수에서 화살표 함수로 표현할 때에, 파라미터가 1개이고, return 문이 한줄일 때에, 콜백함수 내부의 괄호와, 중괄호, return 을 생략할 수 있다. (예)  .find(v => v[1] ===max) 이런식으로.)
  •