본문 바로가기
코테

[JS] 가장 많이 받은 선물_충격적인 얕은 복사

by zenna 2024. 3. 12.
728x90
점수 : 1091 (+7) 
최대 소요시간 : 38.23ms

 

이게 진짜 코테문제였으면 풀다가 멘탈 터졌을 난이도 ^_ㅠ 왜 1단계인걸까

1. 시간 초과를 우려해서 너무 로직을 오래 고민한 점

2. 막상 계획을 다 짜놓고도 배열 순환이 중첩되면 마음이 불안해서 다시 고민한 점

이 두가지 때문에 거의 나흘을 풀었던 문제다. 막상 채점하기 누르니 금방 성공해버려서 놀람.

일단 주석으로 계획을 짜고 문제를 풀어버린 뒤 시간 절약을 고민해보자ㅜㅠ

function solution(friends, gifts) {
  let max = 0; // 리턴할 최대값, 코테 상 answer
  let frhash = {}; // friend 배열을 hash화
  friends.forEach((friend)=> frhash[friend] = 0);
  //frinfr = {친구1 : {친구1: 0, 친구2: 0 ...}, 친구2 : {...}}
  let frinfr = {}; 
  friends.forEach((friend)=> frinfr[friend]= Object.assign({},frhash) ); 
  //gifts : 전체 순회
  gifts.forEach((gift, index)=>{
  	  // giver : 준이, reciever : 받은이
      let [giver,reciever] = gift.split(" "); 
      frinfr[giver][reciever]++; 
      //선물지수+
      frinfr[giver][giver]++;
      frinfr[reciever][reciever]--; // 받은 선물만큼 빼야함
  });
  
  // frhash 순회 시작 : max만 가지고있으면 됨. 
  friends.forEach((one)=>{
      //counting = 체크중인 사람이 받을 선물 개수
      let counting = 0;
      friends.forEach((two)=>{
          if(one != two ){ // 내가 나에게 받은 선물을 확인하진 않음
              let oneC = frinfr[one][two];
              let twoC = frinfr[two][one];

              if ( oneC > twoC || 
                      (oneC == twoC && frinfr[one][one] > frinfr[two][two])){ // one이 선물을 받는 경우
                  counting++;
              }
          }
      });
      max =  Math.max(max,counting);
  });

  return max;
}

이중으로 된 hash 형태를 쓰는데

왜 지정하지도 않은 값들이 자꾸 같이 증가할까 이유를 찾느라 정말 애먹었다.

포기를 할까 싶다가 안쪽 hash 구조가 디버그 모드에서 같이 변경되는걸 보니....

아.....

깊은복사가 안됐구나...

2차원 배열은 얕은복사였지..왜 기억을 못했을까?? 충격적

실무에선 사실 2차원 배열까지 쓸 일이 없어서 아예 생각도 못하고 있었다.

깊은 복사와 얕은 복사 개념 다시 암기

#깊은 복사 #얕은 복사

  • #깊은복사 : 값만 복사. 새로운 주소를 파서 값을 넣는 느낌. 엑셀의 값 붙여넣기
    • 앝은복사를 깊은복사로 : const 변수명 = Object.assign(넣을객체, 원본객체)
  • #얕은복사 : 객체의 참조값(주소)를 복사. 엑셀의 연결해서 붙여넣기. 원본객체와 연결됨
    • 2차원 배열은 얕은복사가 된다.
ex > 
let hash = { ㅁ:0, ㄴ:0, ㄷ:0 };
let newHash1 = { ㄱ : hash, ㄹ:hash } ; // 얕은복사. hash 셋 중에 하나라도 바뀌면 다 바뀜
let newHash2 = { ㄱ : Object.assign({},hash), ㄹ:Object.assign({},hash) } ; // 깊은복사

 

 


주석 없는 버전 

function solution(friends, gifts) {
  let max = 0; 
  let frhash = {}; 
  friends.forEach((friend)=> frhash[friend] = 0);
 
  let frinfr = {}; 
  friends.forEach((friend)=> frinfr[friend]= Object.assign({},frhash) ); 
  
  gifts.forEach((gift, index)=>{
      let [giver,reciever] = gift.split(" "); 
      frinfr[giver][reciever]++; 
      frinfr[giver][giver]++;
      frinfr[reciever][reciever]--; 
  });
  
  friends.forEach((one)=>{
      let counting = 0;
      friends.forEach((two)=>{
          if(one != two ){ 
              let oneC = frinfr[one][two];
              let twoC = frinfr[two][one];

              if ( oneC > twoC || 
                      (oneC == twoC && frinfr[one][one] > frinfr[two][two])){ 
                  counting++;
              }
          }
      });
      max =  Math.max(max,counting);
  });

  return max;
}

728x90

'코테' 카테고리의 다른 글

[JS] 덧칠하기 - 프로그래머스  (0) 2024.03.17
[JS] 추억점수 _ 이걸 한줄로 쓴다고?  (0) 2024.03.13
[JS] 가장 가까운 같은 글자  (0) 2024.03.10
[JS] 삼총사 (프로그래머스)  (0) 2024.03.08
[JS] 푸드 파이트 대회  (0) 2024.03.07

댓글