2026.06.23
주차장의 요금표와 차량이 들어오고(입차) 나간(출차) 기록이 주어졌을 때,
차량별로 주차 요금을 계산하려고 합니다. 아래는 하나의 예시를 나타냅니다.
요금표

입/출차 기록

자동차별 주차 요금

어떤 차량이 입차된 후에 출차된 내역이 없다면, 23:59에 출차된 것으로 간주합니다.
00:00부터 23:59까지의 입/출차 내역을 바탕으로 차량별 누적 주차 시간을 계산하여 요금을 일괄로 정산합니다.
누적 주차 시간이 기본 시간이하라면, 기본 요금을 청구합니다.
누적 주차 시간이 기본 시간을 초과하면, 기본 요금에 더해서, 초과한 시간에 대해서 단위 시간 마다 단위 요금을 청구합니다.
주차 요금을 나타내는 정수 배열 fees, 자동차의 입/출차 내역을 나타내는 문자열 배열 records가 매개변수로 주어집니다. 차량 번호가 작은 자동차부터 청구할 주차 요금을 차례대로 정수 배열에 담아서 return 하도록 solution 함수를 완성해주세요.
fees의 길이 = 4
1 ≤ records의 길이 ≤ 1,000

if (!tempMap.isEmpty()) { // 주차장이 비어 있지 않을 때
for (String key : tempMap.keySet()) { // 남은 차량 시간 정리
int time = 1439 - tempMap.get(key);
resultMap.put(key, time + resultMap.get(key));
}
}
현재 주차장에 있는 차량이 한 번도 나간 기록이 없을 때,
resultMap.get(key) 값은 null이 되는 경우를 고려하지 않음
import java.util.Map;
import java.util.HashMap;
class Solution {
public int[] solution(int[] fees, String[] records) {
Map<String, Integer> tempMap = new HashMap<>(); // 현재 주차장에 남아 있는 차량
Map<String, Integer> resultMap = new HashMap<>(); // 차량이 사용한 총 시간
int defaultTime = fees[0];
int baseFee = fees[1];
int unitTime = fees[2];
int unitFee = fees[3];
for (int i = 0; i < records.length; i++) {
String[] record = records[i].split(" "); // 시간, 차량번호, 출입 내역 나누기
String[] parts = record[0].split(":"); // 시간과 분으로 나누기
int time = Integer.parseInt(parts[0]) * 60 + Integer.parseInt(parts[1]); // 시간과 분을 분으로 변환
if (record[2].equals("IN")) { // 차량이 들어갈 때
tempMap.put(record[1], time); // 차량번호와 들어간 시간 저장
}
else { // 차량이 나올 때
int timeIn = tempMap.get(record[1]); // 차량이 들어간 시간
if (resultMap.get(record[1]) != null) { // 출입 기록이 이미 있는 차량일 때
int timeRemain = resultMap.get(record[1]); // 남아 있던 시간 저장
resultMap.put(record[1], time - timeIn + timeRemain); // 원래 남아 있던 시간 + 사용한 시간
}
else {
resultMap.put(record[1], time - timeIn); // 차량이 사용한 시간 저장
}
tempMap.remove(record[1]); // 주차장에 주차 되어 있던 차량 빼기
}
}
if (!tempMap.isEmpty()) { // 주차장이 비어 있지 않을 때
for (String key : tempMap.keySet()) { // 남은 차량 시간 정리
int time = 1439 - tempMap.get(key);
resultMap.put(key, time + resultMap.get(key));
}
}
int[] answer = new int[resultMap.size()];
int index = 0;
for (String key : resultMap.keySet()) {
int time = resultMap.get(key);
if (time < defaultTime) { // 사용 시간이 기본 시간보다 적을 때
answer[index++] = baseFee;
}
else {
if ((time - defaultTime) % unitTime != 0) {
answer[index++] = baseFee + (((time - defaultTime) / unitTime) + 1) * unitFee;
}
else {
answer[index++] = baseFee + ((time - defaultTime) / unitTime) * unitFee;
}
}
}
return answer;
}
}
차량 번호 순서대로 오름차순 정렬하여 출력해야 함
import java.util.Map;
import java.util.HashMap;
class Solution {
public int[] solution(int[] fees, String[] records) {
Map<String, Integer> tempMap = new HashMap<>(); // 현재 주차장에 남아 있는 차량
Map<String, Integer> resultMap = new HashMap<>(); // 차량이 사용한 총 시간
int defaultTime = fees[0];
int baseFee = fees[1];
int unitTime = fees[2];
int unitFee = fees[3];
for (int i = 0; i < records.length; i++) {
String[] record = records[i].split(" "); // 시간, 차량번호, 출입 내역 나누기
String[] parts = record[0].split(":"); // 시간과 분으로 나누기
int time = Integer.parseInt(parts[0]) * 60 + Integer.parseInt(parts[1]); // 시간과 분을 분으로 변환
if (record[2].equals("IN")) { // 차량이 들어갈 때
tempMap.put(record[1], time); // 차량번호와 들어간 시간 저장
}
else { // 차량이 나올 때
int timeIn = tempMap.get(record[1]); // 차량이 들어간 시간
if (resultMap.get(record[1]) != null) { // 출입 기록이 이미 있는 차량일 때
int timeRemain = resultMap.get(record[1]); // 남아 있던 시간 저장
resultMap.put(record[1], time - timeIn + timeRemain); // 원래 남아 있던 시간 + 사용한 시간
}
else {
resultMap.put(record[1], time - timeIn); // 차량이 사용한 시간 저장
}
tempMap.remove(record[1]); // 주차장에 주차 되어 있던 차량 빼기
}
}
if (!tempMap.isEmpty()) { // 주차장이 비어 있지 않을 때
for (String key : tempMap.keySet()) { // 남은 차량 시간 정리
int time = 1439 - tempMap.get(key);
if (resultMap.get(key) != null) {
resultMap.put(key, time + resultMap.get(key));
}
else {
resultMap.put(key, time);
}
}
}
int[] answer = new int[resultMap.size()];
int index = 0;
for (String key : resultMap.keySet()) {
int time = resultMap.get(key);
if (time < defaultTime) { // 사용 시간이 기본 시간보다 적을 때
answer[index++] = baseFee;
}
else {
if ((time - defaultTime) % unitTime != 0) {
answer[index++] = baseFee + (((time - defaultTime) / unitTime) + 1) * unitFee;
}
else {
answer[index++] = baseFee + ((time - defaultTime) / unitTime) * unitFee;
}
}
}
return answer;
}
}
HashMap과 key 값을 기준으로 오름차순 정렬하는 TreeMap을 사용하여 해결
코드를 작성하기 전 코드 설계부터 하니 이전과 비교했을 때,
확실히 오류가 적어졌음.
다만 여전히 설계를 처음부터 끝까지 꼼꼼히 하는 습관과
문제를 꼼꼼히 읽는 습관이 필요함
import java.util.Map;
import java.util.HashMap;
import java.util.TreeMap;
class Solution {
public int[] solution(int[] fees, String[] records) {
Map<String, Integer> tempMap = new HashMap<>(); // 현재 주차장에 남아 있는 차량
Map<String, Integer> resultMap = new TreeMap<>(); // 차량이 사용한 총 시간
int defaultTime = fees[0];
int baseFee = fees[1];
int unitTime = fees[2];
int unitFee = fees[3];
for (int i = 0; i < records.length; i++) {
String[] record = records[i].split(" "); // 시간, 차량번호, 출입 내역 나누기
String[] parts = record[0].split(":"); // 시간과 분으로 나누기
int time = Integer.parseInt(parts[0]) * 60 + Integer.parseInt(parts[1]); // 시간과 분을 분으로 변환
if (record[2].equals("IN")) { // 차량이 들어갈 때
tempMap.put(record[1], time); // 차량번호와 들어간 시간 저장
}
else { // 차량이 나올 때
int timeIn = tempMap.get(record[1]); // 차량이 들어간 시간
if (resultMap.get(record[1]) != null) { // 출입 기록이 이미 있는 차량일 때
int timeRemain = resultMap.get(record[1]); // 남아 있던 시간 저장
resultMap.put(record[1], time - timeIn + timeRemain); // 원래 남아 있던 시간 + 사용한 시간
}
else {
resultMap.put(record[1], time - timeIn); // 차량이 사용한 시간 저장
}
tempMap.remove(record[1]); // 주차장에 주차 되어 있던 차량 빼기
}
}
if (!tempMap.isEmpty()) { // 주차장이 비어 있지 않을 때
for (String key : tempMap.keySet()) { // 남은 차량 시간 정리
int time = 1439 - tempMap.get(key);
if (resultMap.get(key) != null) {
resultMap.put(key, time + resultMap.get(key));
}
else {
resultMap.put(key, time);
}
}
}
int[] answer = new int[resultMap.size()];
int index = 0;
for (String key : resultMap.keySet()) {
int time = resultMap.get(key);
if (time < defaultTime) { // 사용 시간이 기본 시간보다 적을 때
answer[index++] = baseFee;
}
else {
if ((time - defaultTime) % unitTime != 0) {
answer[index++] = baseFee + (((time - defaultTime) / unitTime) + 1) * unitFee;
}
else {
answer[index++] = baseFee + ((time - defaultTime) / unitTime) * unitFee;
}
}
}
return answer;
}
}
기존 if/else 문으로 null 값을 파악하던 방법과 달리,
getOrDefault()를 이용하여 한 줄로 해결
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
class Solution {
public int[] solution(int[] fees, String[] records) {
Map<String, Integer> tempMap = new HashMap<>();
Map<String, Integer> resultMap = new TreeMap<>();
for (String record : records) {
String[] parts = record.split(" ");
String[] timeParts = parts[0].split(":");
int time = Integer.parseInt(timeParts[0]) * 60 + Integer.parseInt(timeParts[1]);
String carNum = parts[1];
if (parts[2].equals("IN")) {
tempMap.put(carNum, time);
} else {
resultMap.put(carNum, resultMap.getOrDefault(carNum, 0) + time - tempMap.remove(carNum));
}
}
for (String key : tempMap.keySet()) {
resultMap.put(key, resultMap.getOrDefault(key, 0) + 1439 - tempMap.get(key));
}
int[] answer = new int[resultMap.size()];
int idx = 0;
for (int time : resultMap.values()) {
int fee = fees[1];
if (time > fees[0]) {
fee += (int) Math.ceil((double)(time - fees[0]) / fees[2]) * fees[3];
}
answer[idx++] = fee;
}
return answer;
}
}