• 문제 설명
    • 철수는 롤케이크를 두 조각으로 잘라서 동생과 한 조각씩 나눠 먹으려고 합니다. 이 롤케이크에는 여러가지 토핑들이 일렬로 올려져 있습니다. 철수와 동생은 롤케이크를 공평하게 나눠먹으려 하는데, 그들은 롤케이크의 크기보다 롤케이크 위에 올려진 토핑들의 종류에 더 관심이 많습니다. 그래서 잘린 조각들의 크기와 올려진 토핑의 개수에 상관없이 각 조각에 동일한 가짓수의 토핑이 올라가면 공평하게 롤케이크가 나누어진 것으로 생각합니다.

    • 예를 들어, 롤케이크에 4가지 종류의 토핑이 올려져 있다고 합시다. 토핑들을 1, 2, 3, 4와 같이 번호로 표시했을 때, 케이크 위에 토핑들이 [1, 2, 1, 3, 1, 4, 1, 2] 순서로 올려져 있습니다. 만약 세 번째 토핑(1)과 네 번째 토핑(3) 사이를 자르면 롤케이크의 토핑은 [1, 2, 1], [3, 1, 4, 1, 2]로 나뉘게 됩니다. 철수가 [1, 2, 1]이 놓인 조각을, 동생이 [3, 1, 4, 1, 2]가 놓인 조각을 먹게 되면 철수는 두 가지 토핑(1, 2)을 맛볼 수 있지만, 동생은 네 가지 토핑(1, 2, 3, 4)을 맛볼 수 있으므로, 이는 공평하게 나누어진 것이 아닙니다. 만약 롤케이크의 네 번째 토핑(3)과 다섯 번째 토핑(1) 사이를 자르면 [1, 2, 1, 3], [1, 4, 1, 2]로 나뉘게 됩니다. 이 경우 철수는 세 가지 토핑(1, 2, 3)을, 동생도 세 가지 토핑(1, 2, 4)을 맛볼 수 있으므로, 이는 공평하게 나누어진 것입니다. 공평하게 롤케이크를 자르는 방법은 여러가지 일 수 있습니다. 위의 롤케이크를 [1, 2, 1, 3, 1], [4, 1, 2]으로 잘라도 공평하게 나뉩니다. 어떤 경우에는 롤케이크를 공평하게 나누지 못할 수도 있습니다.

    • 롤케이크에 올려진 토핑들의 번호를 저장한 정수 배열 topping이 매개변수로 주어질 때, 롤케이크를 공평하게 자르는 방법의 수를 return 하도록 solution 함수를 완성해주세요.

  • 제한사항
    • 1 ≤ topping의 길이 ≤ 1,000,000
      • 1 ≤ topping의 원소 ≤ 10,000
  • 입출력 예

 

  • 실패 코드 1
    • 먼저 set()을 이용하요 고유한 값들을 체크 한 후 그 값이 동일 하면 공평하게 나누어 진것 이므로 return 값 answer를 1 증가 하는 반복문 작성
    • 해당 방식으로 테스트는 통과 하였으나 제출 하였을 때 시간초과 발생
    • 해당 방식의 시간 복잡도가 O(n2)
def solution(topping):
    answer = 0
    len_t = len(topping)
    for i in range(len_t):
        if i+1 < len_t and len(set(topping[:i])) == len(set(topping[i+1:])): 
            answer += 1
        else: continue
    return answer
  • 실패 코드 2
    • 일단 for문은 동작하는게 맞기에 if절에 있는 len set 하는 부분 수정
    • 왼쪽과 오른쪽을 두어 동일한 set을 가지면 return 값 answer를 1 증가 하는 반복문 작성
    • 이또한 풀고 나니 right_topping을 remove 한는 곳에서 시간 복잡도가 증가
    • 최종적으로 시간 복잡도가 위와 같이 O(n2)
def solution(topping):
    answer = 0
    len_t = len(topping)
    left_topping = set()
    right_topping = set(topping)
    for i in range(len_t):
        left_topping.add(topping[i])
        
        if topping[i] not in topping[i+1:]:
            right_topping.remove(topping[i])
        
        if len(left_topping) == len(right_topping): 
            answer += 1
        else: continue
    return answer

 

  • 성공 코드
    • 파이썬 collections 모듈 의 Counter클래스를 이용하여 지유려는 값이 0이면 right_topping에서 해당 하는 값을 지우는 방식으로 수정
    • 이를 통하여 시간 복잡도가 O(n)이 되어 무사히 통과
from collections import Counter
def solution(topping):
    answer = 0
    len_t = len(topping)
    left_topping = set()
    right_topping = set(topping)
    
    left_counter = Counter()
    right_counter = Counter(topping)
    
    for i in range(len_t):
        left_topping.add(topping[i])
        left_counter[topping[i]] += 1
        
        right_counter[topping[i]] -= 1
        if right_counter[topping[i]] == 0:
            right_topping.remove(topping[i])
        
        if len(left_topping) == len(right_topping): 
            answer += 1
            
    return answer

'Python > Python 문제' 카테고리의 다른 글

2개 이하로 다른 비트  (0) 2024.07.11
숫자 변환하기  (0) 2024.07.05
뒤에 있는 큰 수 찾기  (0) 2024.07.02
피로도  (0) 2024.06.28
프로세스  (0) 2024.06.27

+ Recent posts