ps:problems:programmers:72414
광고 삽입
ps | |
---|---|
링크 | programmers.co.kr/… |
출처 | 프로그래머스 |
문제 번호 | 72414 |
문제명 | 광고 삽입 |
레벨 | Level 3 |
분류 |
구간 합 |
시간복잡도 | O(n+m) |
인풋사이즈 | n<=300,000, m<=360,000 |
사용한 언어 | Python |
해결날짜 | 2021/01/28 |
출처 |
ps:problems:programmers:2021_kakao_blind_recruitment |
풀이
- O(|logs|)에 구간 업데이트를 처리한 뒤, O(play_time)으로 누적 합을 계산한다. 누적합을 계산하고 나면 길이가 adv_time인 각각의 구간의 구간합을 O(1)에 계산할수 있으므로, 모든 구간 중 구간합이 최대값인 구간을 찾는 것은 구간의 갯수인 O(play_time - adv_time) 이다. 그래서 전체 시간 복잡도는 O(n+m), (n=로그의 갯수, m는 플레이타임)
- 구현하지는 않았지만, 다른 방법으로는 스위핑을 사용하는 방법도 있다. 로그의 시작과 끝 두종류 이벤트를 모아서 시간순으로 정렬한 다음, 순서대로 프로세싱하는 방법을 사용하면, m과 관계 없이 O(nlogn)의 시간복잡도로 처리할 수도 있다.
코드
"""Solution code for "Programmers 72414. 광고 삽입".
- Problem link: https://programmers.co.kr/learn/courses/30/lessons/72414
- Solution link: http://www.teferi.net/ps/problems/programmers/72414
"""
def time_to_secs(time):
h, m, s = [int(x) for x in time.split(':')]
return (h * 60 + m) * 60 + s
def solution(play_time, adv_time, logs):
play_time_sec = time_to_secs(play_time) + 1
range_diff = [0] * play_time_sec
prefix_sum = [0] * play_time_sec
for log in logs:
beg, end = [time_to_secs(x) for x in log.split('-')]
range_diff[beg] += 1
range_diff[end] -= 1
range_count = 0
for i in range(1, play_time_sec):
prefix_sum[i] += prefix_sum[i - 1] + range_count
range_count += range_diff[i]
adv_time_sec = time_to_secs(adv_time)
max_view = max((prefix_sum[t + adv_time_sec] - prefix_sum[t], -t)
for t in range(play_time_sec - adv_time_sec))
best_time = -max_view[1]
hh, mm, ss = best_time // 3600, best_time % 3600 // 60, best_time % 60
return f'{hh:02d}:{mm:02d}:{ss:02d}'
ps/problems/programmers/72414.txt · 마지막으로 수정됨: 2021/03/02 04:09 저자 teferi
토론