fees), 입/출차 기록(records)IN 후 OUT 기록이 없으면 23:59에 출차한 것으로 간주한다.기본요금 + ⌈(누적시간 - 기본시간) / 단위시간⌉ * 단위요금 (단, 기본 시간 이내면 기본요금만 청구)처음에는 시(Hour)와 분(Minute)을 따로 계산하려다 복잡해졌다.
18:59 → 18 * 60 + 59 = 1139분출차분 - 입차분)으로 끝난다.parking (HashMap): 현재 주차장에 들어와 있는 차량 관리.IN이면 put, OUT이면 remove를 하여 입차 기록을 지워준다.status (TreeMap): 차량별 누적 주차 시간 관리.TreeMap을 사용했다.records를 순회하며 IN인 경우 parking에 넣고, OUT인 경우 parking에서 꺼내(remove) 차이를 계산 후 status에 누적시킨다.parking에 남아있는(출차 안 한) 차들은 23:59(1439분) 기준으로 시간을 계산해 status에 추가한다.status는 이미 정렬되어 있으므로, 순서대로 요금을 계산하여 결과 리스트에 담는다. import java.util.*;
class Solution {
public int[] solution(int[] fees, String[] records) {
Map<String, Integer> parking = new HashMap<>();
Map<String, Integer> status = new TreeMap<>();
ArrayList<Integer> al = new ArrayList<>();
StringTokenizer st;
for(String s : records) {
st = new StringTokenizer(s);
String time = st.nextToken();
String num = st.nextToken();
String type = st.nextToken();
st = new StringTokenizer(time, ":");
int min = Integer.parseInt(st.nextToken()) * 60
+ Integer.parseInt(st.nextToken());
if(type.equals("IN")) {
parking.put(num, min);
}
else {
int inTime = parking.remove(num);
int parkingTime = min - inTime;
status.put(num, status.getOrDefault(num, 0) + parkingTime);
}
}
Set<String> keySet = parking.keySet();
for(String key : keySet) {
int parkingTime = 23*60 + 59 - parking.get(key);
status.put(key, status.getOrDefault(key, 0) + parkingTime);
}
for(Map.Entry<String, Integer> entry : status.entrySet()) {
int value = entry.getValue();
int fee = 0;
if(value <= fees[0]) {
fee = fees[1];
}
else {
int exceededTime = value - fees[0];
int plusTime = exceededTime % fees[2] > 0 ? 1 : 0;
fee = fees[1] + (exceededTime/fees[2] + plusTime) * fees[3];
}
al.add(fee);
}
int[] answer = al.stream().mapToInt(i -> i).toArray();
return answer;
}
}
처음에는 시와 분을 따로 계산하려다 예외 처리 때문에 고생했다. 시간 차이를 구할 때는 무조건 가장 작은 단위(여기서는 '분')로 환산해서 뺄셈하는 것이 정신 건강에 이롭다는 것을 뼈저리게 느꼈다.
parking 맵은 수시로 넣고 빼야 하므로 속도가 빠른 HashMap을 사용했다.
status 맵은 마지막에 차량 번호 순서대로 결과를 내야 하므로, 입력과 동시에 정렬이 되는 TreeMap을 선택했다.
만약 HashMap만 썼다면 마지막에 keySet을 List로 변환해서 Collections.sort()를 하는 번거로운 과정이 추가되었을 것이다. 자료구조 선택의 중요성을 다시 한번 깨달았다.
기본 시간보다 적게 주차했을 때의 예외 처리를 하지 않아 테스트 케이스에서 실패했었다. 공식에만 의존하지 말고, "기본 요금 조건(누적 시간 <= 기본 시간)"을 먼저 분기 처리(if-else)해주는 것이 안전하다.