반응형
문제가 참 어려웠네요. 문제 이해도 쉽고, 풀고 나서 코드는 참 간단한데 구간 내 트래픽을 구할 방법을 못 찾아서 한참 헤매었습니다. 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 |