본문 바로가기

알고리즘 풀이/프로그래머스

[프로그래머스] 광고 삽입 / 2021 KAKAO BLIND RECRUITMENT - JAVA

🔗 문제 링크

[프로그래머스] 광고 삽입 / 2021 KAKAO BLIND RECRUITMENT - JAVA

 

코딩테스트 연습 - 광고 삽입

시간을 나타내는 HH, H1, H2의 범위는 00~99, 분을 나타내는 MM, M1, M2의 범위는 00~59, 초를 나타내는 SS, S1, S2의 범위는 00~59까지 사용됩니다. 잘못된 시각은 입력으로 주어지지 않습니다. (예: 04:60:24, 11

programmers.co.kr

 

📝 풀이 과정

100시간을 초로 바꾼다면 360,000으로 순차 탐색이 가능하다는 생각이 들었다.

 

먼저 계산을 쉽게 하기 위해 모든 시간을 초로 변환하였고, playCnt배열을 만들어 동영상의 시작시간에 + 1을하고 종료 시간에 - 1을 해주었다.

다음으로 전체 배열을 순회하면서 이전 배열의 값을 누적하였는데 이렇게 하면 현재 동영상을 시청하고 있는 사람의 수가 저장된다. 다시 한 번 더 누적하면 현재 시간까지 동영상을 시청한 총 재생시간이 누적되게 된다.

 

이후, 반복문을 통해 (광고 종료시간 - (광고 시작시간 - 1))을 계산하면 해당 시간동안 재생된 트래픽 수가 나오게 되기 때문에 최대값이 나올 때마다 값을 갱신해 주었다.

 

💻 코드

import java.util.*;

public class Solution {
    public String solution(String play_time, String adv_time, String[] logs) {
        int playTime = timeToSecond(play_time), advTime = timeToSecond(adv_time);

        long[] playCnt = new long[playTime + 1];
        for (String log : logs) {
            String[] split = log.split("-");
            playCnt[timeToSecond(split[0])]++;
            playCnt[timeToSecond(split[1])]--;
        }

        for (int i = 1; i <= playTime; i++) playCnt[i] += playCnt[i - 1];
        for (int i = 1; i <= playTime; i++) playCnt[i] += playCnt[i - 1];

        long maxTime = playCnt[advTime - 1], maxStartTime = 0;
        for (int i = 0; i + advTime <= playTime; i++) {
            long tmp = playCnt[i + advTime] - playCnt[i];

            if (tmp > maxTime) {
                maxTime = tmp;
                maxStartTime = i + 1;
            }
        }

        return String.format("%02d:%02d:%02d", maxStartTime / (60 * 60), (maxStartTime / 60) % 60, maxStartTime % 60);
    }

    int timeToSecond(String str) {
        int[] parse = Arrays.stream(str.split(":")).mapToInt(Integer::parseInt).toArray();
        return parse[0] * 60 * 60 + parse[1] * 60 + parse[2];
    }
}