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