프로그래머스 L1 - 가장 많이 받은 선물

2024. 3. 19. 09:59알고리즘/프로그래머스

https://school.programmers.co.kr/learn/courses/30/lessons/258712

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

해석

이차원 배열을 활용한 구현문제이다.

먼저 이차원배열을 만들어 선물을 주고 받은 관계를 행렬로 표현한다.

이차원배열의 세로줄이 받은 선물의 갯수이고 가로줄이 준 선물의 갯수이다.

이 데이터를 기반으로 map을 만들어서 선물지수를 표현한다.

그리고 이차원 배열을 탐색하면서 조건에 맞는지 확인하면 된다.


코드

function solution(friends, gifts) {
    var answer = 0;
    let map = Array.from({length:friends.length}).map(()=>Array.from({length:friends.length}).fill(0));
    let count = new Map();
    let point = new Map();
    friends.forEach((name)=> count.set(name,0));
    friends.forEach((name)=> point.set(name,0));
    gifts.forEach((e)=>{
        let [a,b] = e.split(" ");
        map[friends.indexOf(a)][friends.indexOf(b)]+=1;
    })
   for(let i = 0;i<map.length;i++){
       let name = friends[i];
       let temp = 0;
       for(let j = 0;j<map.length;j++){
           temp+=map[i][j]-map[j][i];
       }
       point.set(name,temp);
   }
   for(let i = 0;i<map.length;i++){
       for(let j = 0;j<map.length;j++){
           if(i!==j){
               if(map[i][j]>map[j][i]) count.set(friends[i], count.get(friends[i]) + 1);
               else if(map[i][j]<map[j][i]) count.set(friends[j], count.get(friends[j]) + 1);
               else if(map[i][j]===map[j][i]){
                   if(point.get(friends[i])>point.get(friends[j])) count.set(friends[i], count.get(friends[i]) + 1);
                   else if(point.get(friends[i])<point.get(friends[j])) count.set(friends[j], count.get(friends[j]) + 1);
               }
           }
       }
   } 
    for(const v of count.values()){
        answer = Math.max(answer,v);
    }
    return answer;
}

처음에 이렇게 작성했으나 결과값이 예상값보다 2배 커진 상태로 출력되었다.

 

   for(let i = 0;i<map.length;i++){
       for(let j = 0;j<map.length;j++){
           if(i!==j){
               if(map[i][j]>map[j][i]) count.set(friends[i], count.get(friends[i]) + 1);
               else if(map[i][j]<map[j][i]) count.set(friends[j], count.get(friends[j]) + 1);
               else if(map[i][j]===map[j][i]){
                   if(point.get(friends[i])>point.get(friends[j])) count.set(friends[i], count.get(friends[i]) + 1);
                   else if(point.get(friends[i])<point.get(friends[j])) count.set(friends[j], count.get(friends[j]) + 1);
               }
           }
       }
   }

디버깅을 해보니 이 부분에서 중복이 발생했다.

만일 muzi가 frodo에게 준 선물이 받은 선물보다 많으면 muzi가 받아야할 선물 갯수를 하나 증가하고,

그렇지 않으면 frodo가 받아야할 선물 갯수를 하나 증가한다.

그런데 또 frodo가 muzi에게 준 선물이 많은지 받은 선물이 많은지를 중복해서 확인하고 있다.

 

let friends = ['muzi', 'ryan', 'frodo', 'neo'];
let gifts = ['muzi frodo', 'muzi frodo', 'ryan muzi', 'ryan muzi', 'ryan muzi', 'frodo muzi', 'frodo ryan', 'neo muzi'];

function solution(friends, gifts) {
  var answer = 0;
  let map = Array.from({ length: friends.length }).map(() => Array.from({ length: friends.length }).fill(0));
  let count = new Map();
  let point = new Map();
  friends.forEach((name) => count.set(name, 0));
  friends.forEach((name) => point.set(name, 0));
  gifts.forEach((e) => {
    let [a, b] = e.split(' ');
    map[friends.indexOf(a)][friends.indexOf(b)] += 1;
  });
  for (let i = 0; i < map.length; i++) {
    let name = friends[i];
    let temp = 0;
    for (let j = 0; j < map.length; j++) {
      temp += map[i][j] - map[j][i];
    }
    point.set(name, temp);
  }
  for (let i = 0; i < map.length; i++) {
    for (let j = 0; j < map.length; j++) {
      if (i !== j) {
        if (map[i][j] > map[j][i]) count.set(friends[i], count.get(friends[i]) + 1);
        else if (map[i][j] === map[j][i])
          if (point.get(friends[i]) > point.get(friends[j])) count.set(friends[i], count.get(friends[i]) + 1);
      }
    }
  }
  for (const v of count.values()) {
    answer = Math.max(answer, v);
  }

  return answer;
}

console.log(solution(friends, gifts));

따라서 다음과 같이 한번만 카운팅하도록 수정해야한다.