Devtraces
개발자취
Devtraces
전체 방문자
오늘
어제
  • 분류 전체보기
    • Baekjoon
    • Programmers

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 백준
  • Kakao
  • prime number
  • programmers
  • math
  • stack
  • Dijkstra
  • level3
  • recursive
  • map
  • Set
  • 그리디 알고리즘
  • level4
  • greedy
  • Matrix
  • Tree
  • Queue
  • floyd-warshall
  • binary search
  • java
  • sort
  • PriorityQueue
  • dfs
  • level2
  • DP
  • BFS
  • two pointer
  • GCD
  • union-find
  • Trie

최근 댓글

최근 글

티스토리

Devtraces
[프로그래머스 Level.2] 두 큐 합 같게 만들기 (2022 KAKAO TECH INTERNSHIP) (Java)
Programmers

[프로그래머스 Level.2] 두 큐 합 같게 만들기 (2022 KAKAO TECH INTERNSHIP) (Java)

2022. 12. 23. 12:55

문제 링크

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

 

프로그래머스

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

programmers.co.kr

 

 

 

 

코딩테스트 연습 > 2022 KAKAO TECH INTERNSHIP > 두 큐 합 같게 만들기

 

 

문제 설명

 

 

길이가 같은 두 개의 큐가 주어집니다. 하나의 큐를 골라 원소를 추출(pop)하고, 추출된 원소를 다른 큐에 집어넣는(insert) 작업을 통해 각 큐의 원소 합이 같도록 만들려고 합니다. 이때 필요한 작업의 최소 횟수를 구하고자 합니다. 한 번의 pop과 한 번의 insert를 합쳐서 작업을 1회 수행한 것으로 간주합니다.

 

큐는 먼저 집어넣은 원소가 먼저 나오는 구조입니다. 이 문제에서는 큐를 배열로 표현하며, 원소가 배열 앞쪽에 있을수록 먼저 집어넣은 원소임을 의미합니다. 즉, pop을 하면 배열의 첫 번째 원소가 추출되며, insert를 하면 배열의 끝에 원소가 추가됩니다. 예를 들어 큐 [1, 2, 3, 4]가 주어졌을 때, pop을 하면 맨 앞에 있는 원소 1이 추출되어 [2, 3, 4]가 되며, 이어서 5를 insert하면 [2, 3, 4, 5]가 됩니다.

 

다음은 두 큐를 나타내는 예시입니다.

 

queue1 = [3, 2, 7, 2]
queue2 = [4, 6, 5, 1]

 

두 큐에 담긴 모든 원소의 합은 30입니다. 따라서, 각 큐의 합을 15로 만들어야 합니다. 예를 들어, 다음과 같이 2가지 방법이 있습니다.

 

  1. queue2의 4, 6, 5를 순서대로 추출하여 queue1에 추가한 뒤, queue1의 3, 2, 7, 2를 순서대로 추출하여 queue2에 추가합니다. 그 결과 queue1은 [4, 6, 5], queue2는 [1, 3, 2, 7, 2]가 되며, 각 큐의 원소 합은 15로 같습니다. 이 방법은 작업을 7번 수행합니다.
  2. queue1에서 3을 추출하여 queue2에 추가합니다. 그리고 queue2에서 4를 추출하여 queue1에 추가합니다. 그 결과 queue1은 [2, 7, 2, 4], queue2는 [6, 5, 1, 3]가 되며, 각 큐의 원소 합은 15로 같습니다. 이 방법은 작업을 2번만 수행하며, 이보다 적은 횟수로 목표를 달성할 수 없습니다.

 

따라서 각 큐의 원소 합을 같게 만들기 위해 필요한 작업의 최소 횟수는 2입니다.

 

길이가 같은 두 개의 큐를 나타내는 정수 배열 queue1, queue2가 매개변수로 주어집니다. 각 큐의 원소 합을 같게 만들기 위해 필요한 작업의 최소 횟수를 return 하도록 solution 함수를 완성해주세요. 단, 어떤 방법으로도 각 큐의 원소 합을 같게 만들 수 없는 경우, -1을 return 해주세요.

 


제한사항
  • 1 ≤ queue1의 길이 = queue2의 길이 ≤ 300,000
  • 1 ≤ queue1의 원소, queue2의 원소 ≤ 109
  • 주의: 언어에 따라 합 계산 과정 중 산술 오버플로우 발생 가능성이 있으므로 long type 고려가 필요합니다.

 


 

입출력 예
queue1 queue2 result
[3, 2, 7, 2] [4, 6, 5, 1] 2
[1, 2, 1, 2] [1, 10, 1, 2] 7
[1, 1] [1, 5] -1

 


 

입출력 예 설명

 

 

입출력 예 #1

 

문제 예시와 같습니다.

 

 

 

입출력 예 #2

 

두 큐에 담긴 모든 원소의 합은 20입니다. 따라서, 각 큐의 합을 10으로 만들어야 합니다. queue2에서 1, 10을 순서대로 추출하여 queue1에 추가하고, queue1에서 1, 2, 1, 2와 1(queue2으로부터 받은 원소)을 순서대로 추출하여 queue2에 추가합니다. 그 결과 queue1은 [10], queue2는 [1, 2, 1, 2, 1, 2, 1]가 되며, 각 큐의 원소 합은 10으로 같습니다. 이때 작업 횟수는 7회이며, 이보다 적은 횟수로 목표를 달성하는 방법은 없습니다. 따라서 7를 return 합니다.

 

 

 

입출력 예 #3

 

어떤 방법을 쓰더라도 각 큐의 원소 합을 같게 만들 수 없습니다. 따라서 -1을 return 합니다.

 

 

 

 

 

나의 코드

import java.util.*;

class Solution {
    public int solution(int[] queue1, int[] queue2) {
        int answer = 0;
        long sum1 = 0;
        long sum2 = 0;
        
        Queue<Integer> que1 = new LinkedList<>();
        Queue<Integer> que2 = new LinkedList<>();
        
        for(int i=0; i<queue1.length; i++) {
            que1.offer(queue1[i]);
            que2.offer(queue2[i]);
            sum1 += queue1[i];
            sum2 += queue2[i];
        }
        
        if((sum1 + sum2) % 2 != 0)
            return -1;        
        
        while(sum1 != sum2) {
            answer++;
            
            if(sum1 > sum2) {
                que2.offer(que1.peek());
                sum2 += que1.peek();
                sum1 -= que1.peek();
                que1.poll();
            } else {
                que1.offer(que2.peek());
                sum1 += que2.peek();
                sum2 -= que2.peek();
                que2.poll();
            }
            
            // 계속해도 같아질 수 없는 경우 (무한루프)
            // 최대 반복 횟수(대략 queue1 길이 * 3)만큼 돌려도 안된다면 종료
            if(answer > queue1.length * 3)
                return -1;
        }
        
        return answer;
    }
}

 

풀이

  1. 우선 두 개의 큐 q1, q2를 생성하고 배열 queue1과 queue2를 담고 현재 queue1의 원소들의 합과 queue2의 원소들의 합을 저장 할 변수 sum1과 sum2를 long 타입으로 생성하고 각각 원소들의 합을 저장한다.
  2. 혹 sum1과 sum2를 더하여 모든 원소들의 합이 홀수라면 두 큐의 합이 같아질 수 없으므로 -1을 리턴한다.
  3. 그리고 문제에 나온대로 sum1과 sum2가 같아질 때까지 while문을 돌리면서 턴이 진행될 때마다 answer를 1씩 증가신다.
  4. sum1이 더 크다면 q1의 맨 앞에 있는 데이터를 뽑아 q2에 넣어주고 sum2에 더해준다.
    sum2가 더 크다면 q2의 맨 앞에 있는 데이터를 뽑아 q1에 넣어준고 sum1에 더해준다.
  5. 이렇게 while문을 진행하다 sum1과 sum2가 같아지면 while문을 종료하면 된다. 다만 아무리 진행해도 같아지지 않아 무한루프에 빠질 수도 있기 때문에 대략 최대 반복 횟수(queue1.length * 3)만큼 돌려도 같아지지 않는다면 -1을 리턴한다.

 

 

'Programmers' 카테고리의 다른 글

[프로그래머스 Level.2] 테이블 해시 함수 (연습문제) (Java)  (0) 2022.12.28
[프로그래머스 Level.2] 교점에 별 만들기 (위클리 챌린지) (Java)  (0) 2022.12.27
[프로그래머스 Level.2] 가장 큰 수 (정렬) (Java)  (0) 2022.12.23
[프로그래머스 Level.2] 큰 수 만들기 (탐욕법(Greedy)) (Java)  (0) 2022.12.22
[프로그래머스 Level.4] 도둑질 (동적계획법) (Java)  (0) 2022.12.21
    'Programmers' 카테고리의 다른 글
    • [프로그래머스 Level.2] 테이블 해시 함수 (연습문제) (Java)
    • [프로그래머스 Level.2] 교점에 별 만들기 (위클리 챌린지) (Java)
    • [프로그래머스 Level.2] 가장 큰 수 (정렬) (Java)
    • [프로그래머스 Level.2] 큰 수 만들기 (탐욕법(Greedy)) (Java)
    Devtraces
    Devtraces

    티스토리툴바