|
| 1 | +```java |
| 2 | +import java.util.*; |
| 3 | + |
| 4 | +class Solution { |
| 5 | + static class TimeInfo{ |
| 6 | + int startCount; //time에 시작하는 log개수 |
| 7 | + int endCount;//time에 끝나는 log개수 |
| 8 | + long prefix; //time까지의 가중치 누적합 |
| 9 | + |
| 10 | + TimeInfo(int sc, int ec, long p){ |
| 11 | + this.startCount = sc; |
| 12 | + this.endCount = ec; |
| 13 | + this.prefix = p; |
| 14 | + } |
| 15 | + @Override |
| 16 | + public String toString(){ |
| 17 | + return String.format("sc: %d, ec: %d prefix:%d", this.startCount, this.endCount, this.prefix); |
| 18 | + } |
| 19 | + } |
| 20 | + |
| 21 | + private static TreeMap<Integer, TimeInfo> timeInfos; |
| 22 | + public String solution(String play_time, String adv_time, String[] logs) { |
| 23 | + timeInfos = new TreeMap<Integer, TimeInfo>(); |
| 24 | + timeInfos.put(0, new TimeInfo(0, 0, 0)); |
| 25 | + |
| 26 | + for(String log : logs){ |
| 27 | + String[] temp = log.split("-"); |
| 28 | + int startTime = convertToSeconds(temp[0]); |
| 29 | + int endTime = convertToSeconds(temp[1]); |
| 30 | + |
| 31 | + timeInfos.computeIfAbsent(startTime, k -> new TimeInfo(0, 0, 0)).startCount++; |
| 32 | + timeInfos.computeIfAbsent(endTime, k -> new TimeInfo(0, 0, 0)).endCount++; |
| 33 | + } |
| 34 | + |
| 35 | + //prefix 누적합 계산 |
| 36 | + long currentLogs = 0; |
| 37 | + long cumulativeSum = 0; |
| 38 | + Integer prevTime = null; |
| 39 | + for(Map.Entry<Integer, TimeInfo> entry : timeInfos.entrySet()){ |
| 40 | + int time = entry.getKey(); |
| 41 | + TimeInfo info = entry.getValue(); |
| 42 | + |
| 43 | + if(prevTime != null){ |
| 44 | + cumulativeSum += currentLogs * (time - prevTime); |
| 45 | + } |
| 46 | + info.prefix = cumulativeSum; |
| 47 | + currentLogs += info.startCount - info.endCount; |
| 48 | + prevTime = time; |
| 49 | + } |
| 50 | + |
| 51 | + int advSeconds = convertToSeconds(adv_time); |
| 52 | + int playSeconds = convertToSeconds(play_time); |
| 53 | + long maxViewTime = 0; |
| 54 | + int bestStartTime = 0; |
| 55 | + for(int startTime = 0; startTime <= playSeconds - advSeconds; startTime++){ |
| 56 | + int endTime = startTime + advSeconds; |
| 57 | + long viewTime = getViewTime(startTime, endTime); |
| 58 | + |
| 59 | + if(viewTime > maxViewTime){ |
| 60 | + maxViewTime = viewTime; |
| 61 | + bestStartTime = startTime; |
| 62 | + } |
| 63 | + } |
| 64 | + |
| 65 | + return convertToHHMMSS(bestStartTime); |
| 66 | + } |
| 67 | + |
| 68 | + //startTime부터 endTime까지의 총 재생시간 계산 |
| 69 | + private long getViewTime(int startTime, int endTime){ |
| 70 | + long endPrefix = getPrefixSum(endTime); |
| 71 | + long startPrefix = getPrefixSum(startTime); |
| 72 | + return endPrefix - startPrefix; |
| 73 | + } |
| 74 | + |
| 75 | + //time 시점까지의 누적 재생시간 |
| 76 | + private long getPrefixSum(int time){ |
| 77 | + Map.Entry<Integer, TimeInfo> floorEntry = timeInfos.floorEntry(time); |
| 78 | + if(floorEntry == null) return 0; |
| 79 | + |
| 80 | + int floorTime = floorEntry.getKey(); |
| 81 | + TimeInfo floorInfo = floorEntry.getValue(); |
| 82 | + long prefix = floorInfo.prefix; |
| 83 | + |
| 84 | + //구간 내 재생시간 추가 계산 |
| 85 | + if(time > floorTime){ |
| 86 | + long currentLogs = 0; |
| 87 | + // floorTime 이후의 로그 수 계산 |
| 88 | + for(Map.Entry<Integer, TimeInfo> entry : timeInfos.headMap(floorTime, true).entrySet()){ |
| 89 | + TimeInfo info = entry.getValue(); |
| 90 | + currentLogs += info.startCount - info.endCount; |
| 91 | + } |
| 92 | + prefix += currentLogs * (time - floorTime); |
| 93 | + } |
| 94 | + return prefix; |
| 95 | + } |
| 96 | + |
| 97 | + private int convertToSeconds(String hms){ |
| 98 | + String[] tokens = hms.split(":"); |
| 99 | + int result = 0; |
| 100 | + for(int i = 2, gop = 1; i>=0; i--, gop*=60){ |
| 101 | + result += Integer.parseInt(tokens[i])*gop; |
| 102 | + } |
| 103 | + return result; |
| 104 | + } |
| 105 | + |
| 106 | + private String convertToHHMMSS(int seconds){ |
| 107 | + int h = seconds / 3600; |
| 108 | + seconds %= 3600; |
| 109 | + int m = seconds / 60; |
| 110 | + int s = seconds % 60; |
| 111 | + return String.format("%02d:%02d:%02d", h, m, s); |
| 112 | + } |
| 113 | +} |
| 114 | + |
| 115 | +``` |
0 commit comments