본문 바로가기

알고리즘 문제풀이

프로그래머스 광고 삽입 (JAVA)

  • 문제 : 프로그래머스 광고 삽입
 

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

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

programmers.co.kr

문제내용

[문제]

"죠르디"의 동영상 재생시간 길이 play_time, 공익광고의 재생시간 길이 adv_time, 시청자들이 해당 동영상을 재생했던 구간 정보 logs가 매개변수로 주어질 때, 시청자들의 누적 재생시간이 가장 많이 나오는 곳에 공익광고를 삽입하려고 합니다. 이때, 공익광고가 들어갈 시작 시각을 구해서 return 하도록 solution 함수를 완성해주세요. 만약, 시청자들의 누적 재생시간이 가장 많은 곳이 여러 곳이라면, 그 중에서 가장 빠른 시작 시각을 return 하도록 합니다.

[제한사항]

  • play_time, adv_time은 길이 8로 고정된 문자열입니다.
    • play_time, adv_time은 HH:MM:SS 형식이며, 00:00:01 이상 99:59:59 이하입니다.
    • 즉, 동영상 재생시간과 공익광고 재생시간은 00시간 00분 01초 이상 99시간 59분 59초 이하입니다.
    • 공익광고 재생시간은 동영상 재생시간보다 짧거나 같게 주어집니다.
  • logs는 크기가 1 이상 300,000 이하인 문자열 배열입니다.
    • logs 배열의 각 원소는 시청자의 재생 구간을 나타냅니다.
    • logs 배열의 각 원소는 길이가 17로 고정된 문자열입니다.
    • logs 배열의 각 원소는 H1:M1:S1-H2:M2:S2 형식입니다.
      • H1:M1:S1은 동영상이 시작된 시각, H2:M2:S2는 동영상이 종료된 시각을 나타냅니다.
      • H1:M1:S1는 H2:M2:S2보다 1초 이상 이전 시각으로 주어집니다.
      • H1:M1:S1와 H2:M2:S2는 play_time 이내의 시각입니다.
  • 시간을 나타내는 HH, H1, H2의 범위는 00~99, 분을 나타내는 MM, M1, M2의 범위는 00~59, 초를 나타내는 SS, S1, S2의 범위는 00~59까지 사용됩니다. 잘못된 시각은 입력으로 주어지지 않습니다. (예: 04:60:24, 11:12:78, 123:12:45 등)
  • return 값의 형식
    • 공익광고를 삽입할 시각을 HH:MM:SS 형식의 8자리 문자열로 반환합니다.

풀이

문제는 대충 가장많은 시청자 수가 있는 구간을 반환하는 것이라 생각하고 가장 긴 구간 배열을 선언하면 크기가 얼마나 될지 생각했었다. 99시간 59분 59초 대략 100시간이라고 생각하면 100시간 = 6000분 = 360000초 이니 int[360000]은 괜찮을 거라고 생각했다. 그 뒤에 어떤 반복문이 기다릴지는 모르겠지만 일단 그렇게 생각했다. 문제는 동영상의 길이가 문자열로 주어진다는 것이다. 문자열이 주어졌을 때 int 배열의 값을 넣어주기 위해선 문자열을 숫자로 나타내어야만 한다. HH:MM:SS의 형식을 초로 반환하는 함수가 있나? 모른다. 그래서 함수를 세워 구현하였다.

문자열 -> 초(시간) 변환
    static int strToSec(String str) {
        int sec=0;

        String h = str.substring(0,2);
        String m = str.substring(3,5);
        String s = str.substring(6,8);

        sec+= Integer.parseInt(h)*60*60;
        sec+= Integer.parseInt(m)*60;
        sec+= Integer.parseInt(s);

        return sec;
    }

이후 풀이를 위해 구간을 1씩 증가시킬 때마다 광고 안 구간의 시청자 수가 최대가 되게 하기위해서 슬라이딩 윈도우 알고리즘 처럼 큐를 사용해 부분 합을 구해주었다. 이후 광고를 삽입할 구간의 첫번째 시각 문자열을 반환해야하기 때문에 초를 문자열로 반환하는 함수를 세워 리턴하였다.

초(시간) -> 문자열 변환
    static String secToStr(int sec) {
        String str="";

        int s = sec%60; sec/=60;
        int m = sec%60; sec/=60;
        int h = sec;

        if(h<10) str+="0";
        str+=h;
        str+=":";

        if(m<10) str+="0";
        str+=m;
        str+=":";

        if(s<10) str+="0";
        str+=s;

        return str;
    }

전체코드

import java.util.*;
class Solution {
    static int[] view = new int[360000];
    public String solution(String play_time, String adv_time, String[] logs) {
        String answer = "";

        for(String s: logs){
            int start = strToSec(s.substring(0,8));
            int end = strToSec(s.substring(9,17));
            for(int i=start; i<end; i++) view[i]++;
        }

        int play_len = strToSec(play_time);
        int adv_len = strToSec(adv_time);
        int index = 0;
        long sum = 0;
        long maxSum = 0;

        Queue<Integer> q = new LinkedList<>();

        for(int i = 0; i < adv_len; i++) {
            sum+=view[i];
            q.add(view[i]);
        }
        maxSum=sum;

        for(int i = adv_len; i < play_len; i++) {
            sum += view[i];
            q.add(view[i]);
            sum -= q.poll();
            if(sum > maxSum) {
                index = i - adv_len + 1;
                maxSum = sum;
            }
        }
        answer = secToStr(index);
        return answer;
    }

        static int strToSec(String str) {
        int sec=0;

        String h = str.substring(0,2);
        String m = str.substring(3,5);
        String s = str.substring(6,8);

        sec+= Integer.parseInt(h)*60*60;
        sec+= Integer.parseInt(m)*60;
        sec+= Integer.parseInt(s);

        return sec;
    }

    static String secToStr(int sec) {
        String str="";

        int s = sec%60; sec/=60;
        int m = sec%60; sec/=60;
        int h = sec;

        if(h<10) str+="0";
        str+=h;
        str+=":";

        if(m<10) str+="0";
        str+=m;
        str+=":";

        if(s<10) str+="0";
        str+=s;

        return str;
    }
}

결과

image

'알고리즘 문제풀이' 카테고리의 다른 글

프로그래머스 더 맵게 (JAVA)  (0) 2021.08.22
프로그래머스 H-Index (JAVA)  (0) 2021.08.21
[복기] Java - 국민은행 210703  (0) 2021.07.06