https://school.programmers.co.kr/learn/courses/30/lessons/72414
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
문제를 푸는 논리입니다.
전체 동영상 재생시간이 "02:03:55" 로 주어졌다고 가정합니다.
2시간 - > 2 * 60 * 60 초 = 7200
3분-> 3 * 60 초 = 180
55초 = 55
= 7435
timerecord[7435 + 1]의 배열을 만들어줍니다.
그리고 사람들이 동영상을 플레이한 기록인 log를 위와 같이 시분초 형식을 초 형식으로 변환하여 +1 해주면 됩니다.
그 이후 동영상 플레이 길이만큼의 합을 먼저 구해준뒤, 하나씩 갱신하면서 나아가면됩니다.
기억해야할점들
첫번째, String.format 함수로 쉽게 HH:MM:SS 형식을 나타낼 수 있습니다.
https://blog.jiniworld.me/68 를 참고했습니다.
String.format("%02d:%02d:%02d", maxidx/(60*60), (maxidx%(60*60))/60, (maxidx%(60*60))%60);
두번쨰, maxidx, timereocrds[]의 배열인덱스는 시간의 각초를 의미합니다.
timerecords[181]은 3분 1초를 의미합니다. 그러므로 마지막에 시간을 나타낼때 maxidx 값을 연산하여 시간을 리턴해줍니다.
세번째, 초를 hour, minutes, second 로 나타내는연산입니다.
초가 3680 이라고 가정합니다.
3680 / (60 *60 ) = 1시간
(3680 % (60 * 60)) / 60 = (80) / 60 = 1분
(3680 % (60 * 60)) % 60 = 20초
코드입니다.
class Solution { //100시간을 초로변환한 동영상 배열을 선언 public String solution(String play_time, String adv_time, String[] logs) { String answer = ""; int play_time_int = timeConvertToSecondInt(play_time); int adv_time_int = timeConvertToSecondInt(adv_time); System.out.println(play_time_int); System.out.println(adv_time_int); int[] timerecord = new int[play_time_int + 1]; for(String log : logs){ int startlog = timeConvertToSecondInt(log.substring(0,8)); int endlog = timeConvertToSecondInt(log.substring(9,17)); for(int i=startlog;i<endlog;i++){ timerecord[i] += 1; } } int maxidx = 0; long maxtime = 0; for(int i=0;i<adv_time_int;i++){ maxtime += timerecord[i]; } System.out.println(maxtime); long currtime = maxtime; for(int i=adv_time_int; i<play_time_int;i++){ currtime += timerecord[i]; currtime -= timerecord[i - adv_time_int]; if(maxtime < currtime){ maxidx = i - adv_time_int + 1; maxtime = currtime; } } return String.format("%02d:%02d:%02d", maxidx/(60*60), (maxidx%(60*60))/60, (maxidx%(60*60))%60); } public int timeConvertToSecondInt(String timeformat){ String[] temp = timeformat.split(":"); int hour = Integer.parseInt(temp[0]) * 60 * 60; int minute = Integer.parseInt(temp[1]) * 60; int second = Integer.parseInt(temp[2]); return hour + minute + second; } }
네번째, long maxsum을 사용해야합니다.
long maxsum, sum =0 를 사용하여야 제출시 완전한 정답이 됩니다.
- logs는 크기가 1 이상 300,000 이하인 문자열 배열입니다.
그리고 300,000 개의 query, 그리고 시간은 100시간 (100 * 3600)이므로
100 * 3600 * 300,000 = 108,000,000,000 //108억이므로 int는 21억까지 가능하므로 long을 사용하여야 overflow가 나지 않습니다.
다섯번째,
- 동영상 재생시간 = 재생이 종료된 시각 - 재생이 시작된 시각(예를 들어, 00시 00분 01초부터 00시 00분 10초까지 동영상이 재생되었다면, 동영상 재생시간은 9초 입니다.) ↩
이 의미는 01초 부터 10초까지 간다고하면, 1, 2, 3, 4, 5, 6, 7, 8, 9 까지 라는 뜻입니다.
우선 adv_sum 즉, 만약 adv_sum이 10이라고한다면 0초부터 9초까지의 record합을 구합니다.
그 이후 adv_sum=10 부터 새롭게 시작하며 슬라이딩 윈도우를 시작하는데
이떄 최대값보다 크다면 갱신되면서 maxstartindex = 15 - 15 + 1; 을 해줘야 maxstartindex = 1이 됩니다.
마지막값은 초로 포함되지 않기에
maxstartindex = i - adv_sum + 1;
이 계산식이 나옵니다.
for(int i=0;i<adv_sum;i++){ sum += record[i]; // System.out.println(" "+record[i]); } maxsum = sum; maxstartindex = 0; for(int i=adv_sum;i<playtime; i++){ sum += record[i]; sum -= record[i - adv_sum]; if(maxsum < sum){ maxsum = sum; maxstartindex = i - adv_sum + 1; } }
두번쨰 풀어본 코드입니다.
import java.util.*; import java.util.Map.*; import java.io.*; class Solution { int[] record; String answer = ""; public String solution(String play_time, String adv_time, String[] logs) { String[] play_time_temp = play_time.split(":"); int h = Integer.parseInt(play_time_temp[0]); int m = Integer.parseInt(play_time_temp[1]); int s = Integer.parseInt(play_time_temp[2]); int playtime = h * 60 * 60 + m * 60 + s; int[] record = new int[playtime + 1]; for(int i=0;i<logs.length;i++){ String[] temp = logs[i].split("-"); int start_h = Integer.parseInt(temp[0].substring(0,2)); int start_m = Integer.parseInt(temp[0].substring(3,5)); int start_s = Integer.parseInt(temp[0].substring(6,8)); int end_h = Integer.parseInt(temp[1].substring(0,2)); int end_m = Integer.parseInt(temp[1].substring(3,5)); int end_s = Integer.parseInt(temp[1].substring(6,8)); int start = start_h * 60 * 60 + start_m * 60 + start_s; int end = end_h * 60 * 60 + end_m * 60 + end_s; // System.out.println("start "+ start + "end "+ end); for(int j=start; j<end; j++){ record[j] += 1; } } String[] adv_temp = adv_time.split(":"); int adv_h = Integer.parseInt(adv_temp[0]) * 60 * 60; int adv_m = Integer.parseInt(adv_temp[1]) * 60; int adv_s = Integer.parseInt(adv_temp[2]); int adv_sum = adv_h + adv_m + adv_s; long sum = 0; long maxsum = 0; int maxstartindex = 0; for(int i=0;i<adv_sum;i++){ sum += record[i]; // System.out.println(" "+record[i]); } maxsum = sum; maxstartindex = 0; for(int i=adv_sum;i<playtime; i++){ sum += record[i]; sum -= record[i - adv_sum]; if(maxsum < sum){ maxsum = sum; maxstartindex = i - adv_sum + 1; } } // maxstartindex += 1; String answer = String.format("%02d:%02d:%02d", maxstartindex / 3600, (maxstartindex%3600)/60, (maxstartindex%(3600)%60) ); System.out.println(answer); return answer; } }
'알고리즘 > 프로그래머스' 카테고리의 다른 글
[카카오 기출 문제]자물쇠와 열쇠- 레벨 3, 구현 (0) | 2022.11.23 |
---|---|
[카카오 기출 문제]합승 택시 요금- 레벨 3, 다익스트라 + 완전탐색 + 아이디어 + 그래프 (0) | 2022.11.17 |
[카카오 기출 문제]다단계 칫솔 판매- 레벨 3, 링크드리스트 + 트리 + 노드 (0) | 2022.11.13 |
[카카오 기출 문제]등산코스 정하기- 레벨 3, 다익스트라 + 시간초과고려 (0) | 2022.11.11 |
[카카오 기출 문제]n^2 배열 자르기- 레벨 2, 아이디어 (0) | 2022.10.31 |