새소식

알고리즘 테스트 ⏲/프로그래머스

[KAKAO INTERNSHIP] 두 큐 합 같게 만들기 풀이 / JavaScript

  • -
 

프로그래머스

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

programmers.co.kr

 

작성 코드 (1차 시도 / 타임 오버)

function getSum(q) {
  return q.reduce((acc, curr) => acc + curr, 0);
}
function solution(q1, q2) {
  let dest = parseInt((getSum(q1) + getSum(q2)) / 2);
  let tried = 0;
  while (true) {
    let a = getSum(q1);
    let b = getSum(q2);
    if (a === dest) {
      break;
    } else if (a < b) {
      q1.push(q2.shift());
      tried += 1;
    } else if (a > b) {
      q2.push(q1.shift());
      tried += 1;
    }
    if (tried === q1.length * 2) return -1;
  }
  return tried;
}

매번 각 큐의 합을 구하면서 더 적은 합을 가진 큐에 데이터를 넣어주는 방식으로 중간값을 찾아가는 방식입니다. 이 방식은 while문 안에서 getSum-O(n)과 shift-O(n)을 사용하기 때문에 n^2의 복잡도를 가집니다. 실패는 없지만 몇몇 케이스에서 타임오버가 발생합니다. 제한사항을 보면 최악의 경우 300000^2 수 만큼 데이터 연산이 발생하기 때문에 오버될 수 밖에 없었습니다.

 

작성 코드 (2차 시도 / 통과)

function solution(q1, q2) {
    let q1s = q1.reduce((acc, curr) => acc + curr, 0)
    let q2s = q2.reduce((acc, curr) => acc + curr, 0)
    let limit = q1.length * 3
    let dest = parseInt((q1s + q2s) / 2) // 목표값
    let d1 = 0
    let d2 = 0
    let tried = 0
    while (tried !== limit && q1s !== dest) {
        if (q1s < q2s) {
            q1.push(q2[d2])
            q1s += q2[d2]
            q2s -= q2[d2++]
        } else if (q1s > q2s) {
            q2.push(q1[d1])
            q2s += q1[d1]
            q1s -= q1[d1++]
        }
        tried += 1
    }
    return tried === limit ? -1 : tried
}

 

구현 로직

js에는 큐 라이브러리가 없기 때문에 head값만 옮겨주는 배열로 대신하여 사용했습니다. 

예를 들어 일반적인 큐에서 pop 동작은 배열의 start index(0)를 늘려주고(+1) insert 동작은 push로 대신합니다.

만약 변수 d1과 d2가 각각 q1, q2의 start index이고 q1에서 원소를 하나 빼서 q2에 넣어준다고 한다면 q2.push(q1[d1++]) 로 구현할 수 있습니다.

 

q1과 q2 중 더 적은 합을 가진 큐에 상대의 큐에서 값을 빼서 넣어주는 방식으로 계산하면서 목표값을 맞추면 그때의 시도 횟수를 리턴하고 만약 큐 길이의 3배까지 시도했는데도 목표값을 찾지 못한경우는 목표값을 만들기 불가능한 경우이므로 -1을 리턴합니다.

 

여기서 limit값을 2배보다 더 큰 배수로 지정한 이유는 큐에 큰 숫자가 한쪽에 몰려있는 경우 시도 횟수가 큐 길이의 2배 이상 발생할 수 있기 때문에 여유있게 지정합니다.

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.