[프로그래머스] 시소 짝꿍 js

박서연·2023년 1월 25일
4

코테준비

목록 보기
7/8
post-thumbnail

요즘 코딩테스트를 js, c++, c 번갈아가면서 응시하느라 정신이 없다ㅠㅠ
이러다 모든 언어를 까먹을 지도...

최근에는 c++, c로 연습하다가
다시 오랜만에 js로 돌아왔다.

그냥 모든 기업에서 응시 가능한 c++로 계속 연습할까 싶다가도, 프론트엔드 지망생으로써 js를 버릴 수 없다ㅎㅎ

이왕 이렇게 된거 js, c++, c 코테 천재가 되어보겠다!!

오랜만에 js로 푸는 김에 쉬워보이는 새로 나온
문제에 도전!
하지만 문제는 짧은데 level2니까 조금 어려울지도 (풀어보니 어려웠다..ㅎㅎ)


0. 문제 설명

  • 시소는 중심으로부터 2, 3, 4 거리의 지점에 좌석이 하나씩 있음.
  • 완전한 균형을 이루면 두 사람을 시소 짝꿍이라 함. (탑승자 무게 * 시소 축과 좌석 간의 거리)


1. 시간초과

function solution(weights) {
    let answer = 0;
    const distance = [2, 3, 4];
    let t = 0;
    for (let i = 0; i < weights.length; i++)
    {
        for (let j = i + 1; j < weights.length; j++)
        {
            for (let k = 0; k < 3; k++)
            {
                t = 0;
                while (t < 3)
                {
                    if (weights[i] * distance[k] === weights[j] * distance[t])
                    {
                        answer++;
                        break;
                    }
                    t++;
                }
                if (t !== 3)
                    break;
            }
        }
    }
    return answer;
}

4중 반복문이라니 너무하긴 했다.
역시나 시간초과!
이제 어떤 방법으로 시간을 줄일 수 있을지 구상을 해보았다.



2. hmap 사용하기

function solution(weights) {
    let answer = 0;
    let hMap = new Map();
    let friendMap = new Map();
    
    weights.forEach((w, i)=>{ // 사람 수 만큼 돌면서 확인
        let check = [hMap.get(w*2), hMap.get(w*3), hMap.get(w*4)]; //값 경우의 수를 전부 확인!
        check.forEach((data, j)=>{
            if (data === undefined) //이전에 없던 값인 경우 추가
                hMap.set(w * (j + 2) , [i]);
            else
            {
                for (let k = 0; k < data.length; k++) //동일 값을 가진 사람들을 쭉 보고오기
                {
                    if ((friendMap.get(data[k]) !== i) && (friendMap.get(i) !== data[k])) // 이전에 없던 시소 짝궁인 경우
                    {
                        friendMap.set(data[k], i);
                        answer++;
                    }
                }
                data.push(i);
            }
        });
    });

    return answer;
}

hMap에 각 경우별로 숫자들을 넣고, 만약 이미 그 숫자가 있는 경우에는 cntMap에 해당 case를 추가해서 중복이 없으면 추가하는 것으로 진행!

3중 for문이었지만, else로 묶여있고 모든 case를 돌지 않고 작은 값을 돌기 때문에 괜찮지 않을까 생각했다. 7개 정답 -> 13개 정답으로 늘어나긴 했지만 아직 시간 초과가 뜬다는 사실ㅠㅠ

간단한 문제인 줄 알았는데, 은근 안풀린다..



3. {} 사용

function solution(weights) {
    let answer = 0;
    const store = {}; //key-value
    const cal = [1, 3/2, 2, 4/3]; //경우의 수 (1,1), (2,3), (2,4), (3,4)

    weights.sort((a,b)=> b - a).forEach((w) => { //내림차순 정렬 후, 전체 돌면서
        let s;
        cal.forEach((i)=>{
            if( s = w * i, store[s] ){ //해당 비율을 곱한 값이 store에 존재할 경우
              answer += store[s];
            }
        });
        if (!store[w]) store[w] = 1;
        else store[w]++;
    });
    return answer;
}

결국 완전 갈아엎기!!
{} 잘 안사용해 봤는데, 이번에 사용해보니 진짜 편리하다고 느껴졌다. 계속 Map()만 썼는데 얼마나 안예쁜 코드였는지 느껴졌다. 앞으로 {} 애용해야지!!

경우의 수가 (1, 1), (2, 3), (2, 4), (3, 4)라는 힌트를 보고 방법을 바꾸었다.
간결한 코드로 완성~!!

profile
개발자

0개의 댓글