algorithm/programmers

[프로그래머스/자바] 광고 삽입 풀이 - 2021 KAKAO BLIND RECRUITMENT

hsm914 2022. 11. 21. 21:42
728x90

https://school.programmers.co.kr/learn/courses/30/lessons/72414#fnref1

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

2021 KAKAO BLIND RECRUITMENT Level 3 문제다.

 

 

 

문제를 접근할 때까지 꽤나 시간이 걸렸던 문제인데, 접근을 잘 한다면 그 후에는 어렵지 않다.

먼저 각 초마다 몇명의 사람이 재생하고 있는지를 저장할 배열 time[]을 생성한다.

예를 들어 time[5] = 3 일 경우 5초에 3명의 사람이 영상을 재생하고 있는 것이다.

 

logs의 원소 하나하나씩 돌면서 원소의 범위에 맞게 time에 1씩 더한다.

 

그리고 광고시간만큼의 구간을 설정해 처음부터 영상시간 끝까지 돌면서 최대 누적 재생시간을 찾는다.

구간의 초기값은 0부터 광고시간만큼이다.

앞의 1초씩 빼고 뒤의 1초씩 더하면서 구간을 1초 이동하는 것을 반복한다.

최대값이 갱신된다면 ans에 구간의 시작점을 저장한다.

 

마지막으로 ans를 String으로 변환한 값을 return하면 된다.

 

 

 

주의할점

1)

ans의 초기값을 잘 설정해줘야 한다.

0값이 아닌 다른 값으로 지정한다면,

0으로 시작하는 구간의 누적 재생시간이 가장 큰 경우 0을 return 하지 않고 

ans의 초기값으로 반환된다. (if문을 한번도 만족하지 않기 때문에 ans가 갱신되지 않음)

 

2)

그리고 if문을 만족하는 경우, ans = i가 아닌 ans = i + 1이다.

i는 for문의 현재 구간 sum의 시작점이 아니다.

sum에서 i를 빼고 j를 더해 새로운 구간을 만들었기 때문에

구간의 시작점은 i + 1이 된다.

 

3)

logs를 탐색하며 초마다 누적 재생시간을 계산할 때, logs의 가장 마지막 구간은 계산하지 않는다.

문제 가장 마지막 설명에 아래와 같이 나와있다.

 

동영상 재생시간 = 재생이 종료된 시각 - 재생이 시작된 시각(예를 들어, 00시 00분 01초부터 00시 00분 10초까지 동영상이 재생되었다면, 동영상 재생시간은 9초 입니다.) 

 

즉, 00:00:01-00:00:10일 때 9초인 것이므로 1초부터 9초까지 1씩 더해줘야 한다. 10초는 제외한다.

 

 

 

배운점 및 느낀점

다른 분의 풀이를 약간만 참고하면 코드를 구현하기까지 간단한데,

혼자 생각해내려고 하면 왜이렇게 어려운지 모르겠다.

카카오가 기본적인 알고리즘을 더 꼬아서 응용하는 문제를 많이 내서 그런 것 같다.

자꾸 더 어렵게 생각하고 특정 알고리즘을 적용하려는 습관이 있는듯...

 

 

class Solution {
    public String solution(String play_time, String adv_time, String[] logs) {
        if(play_time.equals(adv_time))
        	return "00:00:00";
        
        int play = strToSec(play_time);
        int adv = strToSec(adv_time);
        
        int[] time = new int[play + 1];
        
        for(int i=0;i<logs.length;i++) {
        	String[] temp = logs[i].split("-");
        	int start = strToSec(temp[0]);
        	int end = strToSec(temp[1]);
        	
        	for(int j=start;j<end;j++)
        		time[j]++;
        }
        
        long sum = 0;
        
        for(int i=0;i<adv;i++)
        	sum += time[i];
        
        long max = sum;
        
        int ans = 0;
        
        for(int i=0,j=adv;j<play;i++,j++) {
        	// 1초씩 구간 옮기기
        	sum -= time[i];
        	sum += time[j];
        	
        	if(max < sum) {
        		max = sum;
        		ans = i + 1;
        	}
        }
        
        return secToStr(ans);
    }
	
	static int strToSec(String str) {
		String[] arr = str.split(":");
		
		return Integer.parseInt(arr[0]) * 3600 + 
				Integer.parseInt(arr[1]) * 60 + 
				Integer.parseInt(arr[2]);
	}
	
	static String secToStr(int sec) {
		// HH
		String str = sec / 3600 > 9 ? "" : "0";
		str += String.valueOf(sec / 3600) + ":";
		sec %= 3600;
		
		// MM
		str += sec / 60 > 9 ? "" : "0";
		str += String.valueOf(sec / 60) + ":";
		sec %= 60;
		
		// SS
		str += sec > 9 ? "" : "0";
		str += String.valueOf(sec);

		return str;
	}
}
728x90