codingtest

롤케이크 자르기

2026-08-23
2분 분량
JAVA프로그래머스

문제 링크

문제 요약

  • topping 배열은 롤케이크에 일렬로 올라간 토핑 번호다
  • 한 지점을 잘라 두 조각으로 나눴을 때, 양쪽 토핑 종류 수가 같아야 공평하게 나눈 것이다
  • 공평하게 자를 수 있는 방법의 수를 구하는 문제다

문제 풀이

처음에는 자르는 위치마다 왼쪽과 오른쪽 배열을 나눠서 각각 서로 다른 토핑 종류를 세면 되겠다고 생각했다.

하지만 topping의 길이가 최대 1,000,000인데, 자를 수 있는 위치도 그만큼 많다.

매 위치마다 왼쪽과 오른쪽을 처음부터 다시 세면 위치 하나당 O(n)이 걸리고, 이를 모든 위치에 대해 반복하면 O(n²)이 되어 시간 초과가 난다.

이 문제의 핵심은 자르는 위치를 하나씩 오른쪽으로 옮길 때, 토핑 하나가 오른쪽에서 왼쪽으로 넘어가는 것뿐이라 종류 수를 처음부터 다시 셀 필요가 없다는 점이다.

  • 먼저 오른쪽 카운트 배열을 topping 전체로 채워서, 전체가 오른쪽에 있는 상태에서 시작한다
  • 왼쪽으로 하나씩 옮기면서, 그 토핑이 왼쪽에 처음 등장하면 leftKinds를 늘리고, 오른쪽에서 그 토핑이 완전히 사라지면 rightKinds를 줄인다
  • 옮긴 직후 leftKinds와 rightKinds가 같으면 그 자리가 공평한 절단선이므로 answer를 늘린다

마지막 토핑을 옮기고 나면 오른쪽 조각이 비어버리므로, 반복은 topping.length - 1까지만 돈다.

최종 코드

java
class Solution {
    public int solution(int[] topping) {
        int answer = 0;
        int[] rightCount = new int[10001]; // 오른쪽 조각에 남은 토핑별 개수
        boolean[] leftHas = new boolean[10001]; // 왼쪽 조각에 등장한 적 있는 토핑

        int rightKinds = 0;
        int leftKinds = 0;

        // 처음에는 전체 토핑이 오른쪽 조각에 있는 상태로 시작
        for (int t : topping) {
            if (rightCount[t] == 0) {
                rightKinds++;
            }
            rightCount[t]++;
        }

        for (int i = 0; i < topping.length - 1; i++) {
            int t = topping[i];

            // 토핑 하나를 왼쪽으로 옮긴다
            if (!leftHas[t]) {
                leftHas[t] = true;
                leftKinds++;
            }

            rightCount[t]--;

            if (rightCount[t] == 0) {
                rightKinds--;
            }
            if (leftKinds == rightKinds) {
                answer++;
            }
        }

        return answer;
    }
}

함께 읽으면 좋은 글

코딩 테스트2026-08-23

택배상자

order 배열은 택배 기사님이 원하는 상자 적재 순서다 기존 컨테이너 벨트는 1번부터 순서대로만 꺼낼 수 있다 보조 벨트는 스택처럼 마지막에 넣은 것부터 꺼낼 수 있다 원하는 순서대로 최대한 실을 수 있는 상자 개수를 구하는 문제다 처음에는 기존 벨트를 실제 리스트로 만들어…

코딩 테스트2026-08-23

할인 행사

want, number 배열로 정현이가 원하는 제품과 수량을 표현한다 discount 배열은 XYZ 마트가 매일 할인하는 제품 목록이다 연속된 10일 동안 할인 제품 종류와 수량이 want, number와 정확히 일치해야 회원가입할 수 있다 그런 시작일이 총 몇 번 있는지…

코딩 테스트2026-08-23

숫자 변환하기

자연수 x를 y로 바꾸는 데 x+n, x2, x3 세 가지 연산을 쓸 수 있다 x를 y로 바꾸는 최소 연산 횟수를 구하는 문제다 만들 수 없으면 -1을 반환한다 처음에는 x에서 시작해서 세 가지 연산을 재귀적으로 다 시도해보고 y에 도달하는 경로 중 가장 짧은 걸 고르면…

코딩 테스트2026-08-23

두 원 사이의 정수 쌍

원점이 중심인 두 원이 있고 반지름은 각각 r1, r2다 (r1 < r2) 두 원 사이 공간에서 x, y 좌표가 모두 정수인 점의 개수를 구하는 문제다 원 위의 점도 포함해서 센다 처음에는 x, y 좌표를 이중 for문으로 전부 돌면서 각 점이 두 원 사이에 있는지 판별하면…