코딩 테스트/프로그래머스

프로그래머스 - 광고 삽입 문제 (자바)

programmers.co.kr/learn/courses/30/lessons/72414

 

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

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

programmers.co.kr

99:59:59을 초로하면 35999초이므로 

각 초마다 viewer의 수를 배열로 만들고 누적값을 통해서 해결하였습니다.

 

1. 영상의 길이, 광고의 길이를 초단위로 변경

2. 영상의 길이까지 담을 수 있는 int배열 생성

3. 로그들을 순회하면서 배열에 +1 - 다만 끝나는 지점은 +1 하지않음(끝점을 포함하지않고 계산해야하기 때문)

4. 0초에 광고를 삽입한다고 가정했을대의 누적값을 구함

5. 광고의 시작과 끝을 +1 씩하면서 누적값을 비교함

 - 시작시간의 viewer 수를 뺌

 - 종료시간의 viewer 수를 더 함

 - 비교해서 크면 max값으로 둠

 

주의점

1. 누적값이 int자료형의 범위를 초과하는 테스트 케이스가 있으므로 long을 사용

2. 종료시점은 누적값에서 계산되지않아야합니다.

 

ps

3, 23, 24번 테스트 케이스가 실패하면 초를 문자로 바꾸는 부분에 문제가 있을수 있습니다... 제가 9보다 크면으로 해야할걸 10으로 해서 경험했습니다 ..ㅠㅠ

// 프로그래머스 광고 삽입 문제
class InsertAd {
    public String solution(String play_time, String adv_time, String[] logs) {
        int playTime = strToSecond(play_time);
        int advTime = strToSecond(adv_time);
        int[] counts = new int[playTime + 1]; // playTime의 값까지 포함해야함으로 +1

        for (String log : logs) {
            String[] splits = log.split("-");
            int startViewTime = strToSecond(splits[0]);
            int endViewTime = strToSecond(splits[1]);

            // viewer 의 시작부터 끝까지 +1 - 종료 시점은 본것아니므로 < 부등호 사용
            for (int i = startViewTime; i < endViewTime; i++) {
                counts[i]++;
            }
        }

        // 0초에 광고를 넣는 다고가정 했을때 누적 값을 계산
        int startTime = 0;
        int endTime = advTime;
        long sum = 0;
        for (int i = startTime; i < endTime; i++) {
            sum += counts[i];
        }

        // 누적값에서 앞에 값을 빼고 뒤에 값을 추가하면서 각초마다 광고를 넣었을때의 누적값을 구하고 비교
        long max = sum;
        int maxStartTime = 0;
        while (endTime <= playTime) {
            sum -= counts[startTime];
            sum += counts[endTime];
            if(sum > max) {
                max = sum;
                maxStartTime = startTime + 1;
            }
            startTime++;
            endTime++;
        }
        return secondToStr(maxStartTime);
    }

    static int strToSecond(String str) {
        String[] split = str.split(":");
        return Integer.parseInt(split[0]) * 60 * 60 + Integer.parseInt(split[1]) * 60 + Integer.parseInt(split[2]);
    }

    static String secondToStr(int time) {
        int hour = time / 3600;
        time %= 3600;
        int minute = time / 60;
        int second = time % 60;

        String strHour = hour > 9 ?  String.valueOf(hour) : "0" + hour;
        String strMinute = minute > 9 ?  String.valueOf(minute) : "0" + minute;
        String strSecond = second > 9 ?  String.valueOf(second) : "0" + second;

        return String.join(":", strHour, strMinute, strSecond);
    }
}