동영상 재생기는 세 가지 기능을 지원한다.
prev: 현재 위치에서 10초 전으로 이동next: 현재 위치에서 10초 후로 이동입력으로는 다음 값들이 주어진다.
video_len: 동영상 길이pos: 현재 재생 위치op_start: 오프닝 시작 시각op_end: 오프닝 종료 시각commands: 사용자가 입력한 명령 목록모든 명령을 처리한 뒤의 재생 위치를 "mm:ss" 형식으로 반환해야 한다.
시간이 "mm:ss" 문자열로 주어지기 때문에 그대로 계산하면 번거롭다.
따라서 모든 시간을 초 단위 정수로 변환한 뒤 계산하고, 마지막에 다시 "mm:ss" 형식으로 바꾸면 된다.
예를 들어 "10:05"는 다음처럼 변환한다.
10분 5초 = 10 * 60 + 5 = 605초
문자열 시간을 초 단위로 바꾸는 함수다.
def to_seconds(time):
minute, second = map(int, time.split(":"))
return minute * 60 + second
초 단위 시간을 다시 "mm:ss" 형식으로 바꾸는 함수다.
def to_time(seconds):
minute = seconds // 60
second = seconds % 60
return f"{minute:02d}:{second:02d}"
f"{minute:02d}"는 숫자를 두 자리로 맞춰준다.
예를 들어 3은 "03"이 된다.
현재 위치가 오프닝 구간 안에 있다면 오프닝 종료 시각으로 이동해야 한다.
문제에서 오프닝 구간은 다음 조건을 포함한다.
op_start <= 현재 위치 <= op_end
따라서 다음과 같이 처리할 수 있다.
def skip_opening(current):
if op_start_sec <= current <= op_end_sec:
return op_end_sec
return current
주의할 점은 명령을 실행하기 전에도 현재 위치가 오프닝 구간일 수 있다는 것이다.
그래서 각 명령을 처리하기 전에 한 번, 명령을 처리한 뒤에 한 번 오프닝 건너뛰기를 적용하면 안전하다.
prev 명령은 10초 전으로 이동한다.
단, 현재 위치가 10초 미만이면 영상의 처음인 0초로 이동한다.
current = max(0, current - 10)
next 명령은 10초 후로 이동한다.
단, 남은 시간이 10초 미만이면 영상의 마지막 위치로 이동한다.
current = min(video_len_sec, current + 10)
def solution(video_len, pos, op_start, op_end, commands):
def to_seconds(time):
minute, second = map(int, time.split(":"))
return minute * 60 + second
def to_time(seconds):
minute = seconds // 60
second = seconds % 60
return f"{minute:02d}:{second:02d}"
video_len_sec = to_seconds(video_len)
current = to_seconds(pos)
op_start_sec = to_seconds(op_start)
op_end_sec = to_seconds(op_end)
def skip_opening(current):
if op_start_sec <= current <= op_end_sec:
return op_end_sec
return current
current = skip_opening(current)
for command in commands:
current = skip_opening(current)
if command == "prev":
current = max(0, current - 10)
elif command == "next":
current = min(video_len_sec, current + 10)
current = skip_opening(current)
return to_time(current)
다음과 같은 입력이 있다고 하자.
video_len = "34:33"
pos = "13:00"
op_start = "00:55"
op_end = "02:55"
commands = ["next", "prev"]
초 단위로 변환하면 다음과 같다.
video_len = 2073
pos = 780
op_start = 55
op_end = 175
처리 과정은 다음과 같다.
현재 위치: 13:00
next 실행
13:00 -> 13:10
prev 실행
13:10 -> 13:00
최종 위치는 다음과 같다.
13:00
명령의 개수를 N이라고 하자.
각 명령은 한 번씩만 처리하고, 각 처리 과정은 모두 상수 시간에 끝난다.
따라서 시간 복잡도는 다음과 같다.
O(N)
공간 복잡도는 몇 개의 정수 변수만 사용하므로 다음과 같다.
O(1)
이 문제의 핵심은 문자열 시간 계산을 직접 하지 않는 것이다.
"mm:ss" 형식의 시간을 초 단위 정수로 바꾸면 prev, next, 오프닝 건너뛰기 처리를 모두 간단한 숫자 계산으로 해결할 수 있다.
또한 현재 위치가 오프닝 구간에 포함되면 자동으로 op_end로 이동해야 하므로, 명령 처리 전후에 오프닝 체크를 해주는 것이 중요하다.