Algorithm

[프로그래머스] 롤케이크 자르기

비번변경 2024. 1. 24. 15:11

문제

문제 : https://school.programmers.co.kr/learn/courses/30/lessons/132265

 

철수는 여러 토핑이 일렬로 올려진 롤케이크를 두 조각으로 잘라서 동생과 한 조각씩 나눠 먹으려고 한다. 두 사람은 조각의 크기보다 토핑의 종류를 더 중요하게 생각해, 각 조각에 올라간 토핑의 가짓수가 동일하면 공평하게 나눈 거라 생각한다.

예로 들어, 롤케이크에 4가지 종류의 토핑이 올라가 있고 그 토핑을 1, 2, 3, 4와 같은 번호로 표시했을 때 롤케이크의 토핑은 [1, 2, 1, 3, 1, 4, 1, 2]라고 표현할 수 있다. 이 롤케이크를 공평하게 나눈 경우는 [1, 2, 1, 3], [1, 4, 1, 2] 또는 [1, 2, 1, 3, 1], [4, 1, 2]가 될 수 있다.

 

롤케이크에 올려진 토핑의 번호를 저장한 배열 topping이 매개변수로 주어질 때, 롤케이크를 공평하게 자르는 방법을 구하라.

 

틀린 풀이

단순하게 topping의 각 사이를 자르고, set으로 토핑의 중복을 제거한 길이를 비교한다.

def solution(topping):
    answer = 0
    
    for i in range(1, len(topping)):
        if len(set(topping[i:])) == len(set(topping[:i])):
            answer += 1

    return answer

제한사항에서 topping의 길이가 1,000,000이라 이 방법은 시간 초과가 발생한다. 매번 철수와 동생 몫의 롤케이크를 새로 구성하지 않는 등의 효율적인 방법이 필요하다.

 

 

맞은 풀이

매번 철수와 동생 몫의 롤케이크를 새로 구성하지 않기 위해서 각 조각을 set과 Counter를 활용해 초기화한다. 그리고 토핑 사이를 잘라가면서 토핑의 종류를 비교한다.

구현은 다음과 같다.

 

1. 토핑을 더해가는 조각은 빈 set으로 선언한다.

a = set()

2. 토핑을 빼가는 조각은 Counter을 이용해 각 토핑의 번호와 그 개수로 초기화한다.

b = Counter(topping)

 

3. topping의 각 사이를 자른다.

set에는 토핑을 add 하고, counter에서는 토핑의 개수를 하나 줄인다. 만약 줄인 결과가 0이면 counter에서 토핑에 해당하는 키를 제거한다.

4. set의 길이와 counter 키의 길이를 비교한다.

for t in topping:
    a.add(t)
    b[t] -= 1
    if b[t] == 0:   b.pop(t)
        
    if len(a) == len(b):
        answer += 1

 

전체 코드는 접은 글로 작성해둔다.

더보기
from collections import Counter

def solution1(topping):
    answer = 0
    
    a = set()
    b = Counter(topping)
    for t in topping:
        a.add(t)
        
        b[t] -= 1
        if b[t] == 0:   b.pop(t)
        
        if len(a) == len(b):
            answer += 1

    return answer

 

 

참고 문서

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