반응형
문제가 참 어려웠네요. 문제 이해도 쉽고, 풀고 나서 코드는 참 간단한데 구간 내 트래픽을 구할 방법을 못 찾아서 한참 헤매었습니다. Date클래스로 포맷팅 하면 끝날 줄 알았는데 본격적인 문제의 시작은 그다음이더군요. 별의별 생각을 다하다가(밀리세컨드 단위로 늘려야 하나 같은..) 시작점부터 1초까지를 모두 카운트했다가 실패하고, 카카오 해설의 요청량이 변하는 순간은 각 로그의 시작과 끝뿐임을 알 수 있습니다.
이 말을 키포인트로 풀었습니다.
Traffic 클래스
- startTime, endTime을 Date의 long형식으로 가지고 있고, float로 processTime(작업시간)을 들고 있습니다.
- Traffic 생성자에서는 parseLog 메서드를 통해 SimpleDateFormat으로 "yyyy-MM-dd hh:mm:ss.SSS"형식의 데이터로 파싱하여 startTime, endTime을 계산하여 넣습니다. 마찬가지로 s문자열을 잘라내어 Float으로 파싱 하여 processTime에 저장합니다.
getCountMax 메서드
- startSection ~ endSection (1초)간에 이 값 사이에 있는 트래픽을 찾아냅니다.
(1) startTime이 startSection보다 크고, startTime이 endSection보다 작은 경우
(2) endTime이 startSection보다 크고, endTime이 endSection보다 작은 경우
(3) startTime이 startSection보다 작고, endTime이 startSection보다 큰 경우
위 세가지 경우일 때 트래픽은 해당 구간 안에 포함되어 있기 때문에 count를 증가시켜, 가장 트래픽이 많은 구간을 찾아냅니다. 이때, 요청량이 변하는 순간은 각 로그의 시작과 끝 + 1초 구간이기 때문에, 해당 구간을 startSection에 넣어 구간을 산정합니다.
아래 사진의 주황색으로 표시한 부분이 위 (1), (2), (3) 조건에 해당하는 부분입니다.
solution
- 들어온 Log값을 Traffic 클래스를 통해 파싱하여 startTime, endTime을 저장하고, List에 저장해둡니다.
- getCountMax 메서드를 호출하여, startSection에 startTime을 넣은 구간의 최대 카운트를 answer에 넣습니다.
- getCountMax 메서드를 호출하여, startSection에 endTime을 넣은 구간의 최대 카운트를 answer에 넣습니다.
- 결과를 반환합니다.
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
class Solution {
public int solution(String[] lines) {
int answer = 0;
List<Traffic> trafficList = new ArrayList<Traffic>();
for (String line : lines){
trafficList.add(new Traffic(line));
}
// 요청량이 변하는 순간은 각 로그의 시작과 끝뿐이다.
answer = getCountMax(trafficList, true, answer);
answer = getCountMax(trafficList, false, answer);
return answer;
}
private int getCountMax (List<Traffic> trafficList, boolean isStart, int maxCount){
for (int i = 0; i <trafficList.size(); ++i){
int count = 0;
long startSection = isStart ? trafficList.get(i).startTime : trafficList.get(i).endTime;
long endSection = startSection + 1000;
for (int j = 0; j < trafficList.size(); ++j) {
if ((startSection <= trafficList.get(j).startTime && trafficList.get(j).startTime < endSection)
|| (startSection <= trafficList.get(j).endTime && trafficList.get(j).endTime < endSection)
|| (trafficList.get(j).startTime <= startSection && endSection <= trafficList.get(j).endTime)) {
count++;
}
maxCount = Math.max(maxCount, count);
}
}
return maxCount;
}
}
class Traffic {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
long startTime;
long endTime;
float processingTime;
Traffic(String line){
parseLog(line);
}
private void parseLog(String line){
String[] logs = line.split(" ");
this.processingTime = Float.parseFloat(logs[2].split("s")[0]);
try {
this.endTime = dateFormat.parse(logs[0] + " " + logs[1]).getTime();
this.startTime = endTime - (long)(processingTime*1000) + 1;
} catch (Exception e){
System.out.println("데이터 포맷 에러");
e.printStackTrace();
}
}
}
반응형
'개발 > 알고리즘' 카테고리의 다른 글
[프로그래머스][2019 KAKAO BLIND RECRUITMENT] 길찾기 게임 Level 3 (Java) (0) | 2021.01.11 |
---|---|
[프로그래머스][월간 코드 챌린지 시즌1] 스타수열 문제 해결 (Java) Level 3 (1) | 2021.01.10 |