문제 : https://school.programmers.co.kr/learn/courses/30/lessons/92341
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
처음 작성한 코드 (정답 코드)
import java.util.*;
class Solution {
public int[] solution(int[] fees, String[] records) {
HashMap<String, String> inMap = new HashMap<>();
HashMap<String, Integer> totalTimeMap = new HashMap<>();
for (String record : records) {
String[] splitRecord = record.split(" ");
String time = splitRecord[0];
String carNumber = splitRecord[1];
String contents = splitRecord[2];
if (contents.equals("IN")) {
inMap.put(carNumber,time);
}
else {
totalTimeMap.merge(carNumber, timeCal(inMap.get(carNumber), time), Integer::sum);
inMap.remove(carNumber);
}
}
// 출차가 없는 애들 계산
for (Map.Entry<String, String> entry : inMap.entrySet()) {
totalTimeMap.merge(entry.getKey(), timeCal(entry.getValue(), "23:59"), Integer::sum);
}
List<Integer> answer = new ArrayList<>();
List<String> keySet = new ArrayList<>(totalTimeMap.keySet());
Collections.sort(keySet);
for (String key : keySet) {
answer.add(computeFee(fees, totalTimeMap.get(key)));
}
// 결과 리턴
return answer.stream().mapToInt(i->i).toArray();
}
public static int timeCal(String inTime, String outTime) {
String[] splitInTime = inTime.split(":");
String[] splitOutTime = outTime.split(":");
return (Integer.parseInt(splitOutTime[0])*60 + Integer.parseInt(splitOutTime[1]))
- (Integer.parseInt(splitInTime[0])*60 + Integer.parseInt(splitInTime[1]));
}
public static int computeFee(int[] fees, int time) {
// 요금 정리
int basicTime = fees[0];
int basicFee = fees[1];
int unitTime = fees[2];
int unitFee = fees[3];
int totalFee = basicFee;
// 계산
time -= basicTime;
if (time <= 0) return totalFee;
double doubleTime = time;
totalFee += (int) (Math.ceil(doubleTime/unitTime) * unitFee);
return totalFee;
}
}
수정했으면 좋았을 부분
- HashMap -> TreeMap
HashMap<String, Integer> totalTimeMap = new HashMap<>();
HashMap이 아니라 TreeMap을 썼다면 자동으로 오름차순으로 정렬되기 때문에
Collections.sort(keySet);
위와 같은 정렬 코드를 쓸 필요가 없어진다.
- 더 좋은 알고리즘
HashMap<String, String> inMap = new HashMap<>();
HashMap<String, Integer> totalTimeMap = new HashMap<>();
for (String record : records) {
String[] splitRecord = record.split(" ");
String time = splitRecord[0];
String carNumber = splitRecord[1];
String contents = splitRecord[2];
if (contents.equals("IN")) {
inMap.put(carNumber,time);
}
else {
totalTimeMap.merge(carNumber, timeCal(inMap.get(carNumber), time), Integer::sum);
inMap.remove(carNumber);
}
}
// 출차가 없는 애들 계산
for (Map.Entry<String, String> entry : inMap.entrySet()) {
totalTimeMap.merge(entry.getKey(), timeCal(entry.getValue(), "23:59"), Integer::sum);
}
작성한 코드에서 입차를 Map에 집어넣고, 출차 시 Map에서 꺼내서 시간을 계산해서 totalTimeMap에 집어넣는다. 그리고 입차 기록만 있는 차들을 다시 한 번 순회하면서 계산하여 totalTimeMap에 집어넣는다.
하지만 입차할 때 [입차 ~ "23:59"]시간을 totalTimeMap에 넣어두고, 출차 시 totalTimeMap에 넣어둔 값에서 [출사 ~ "23:59"] 시간을 빼주는 방법으로 코드를 짠다면 inMap을 구현할 필요도 없고 전체 순회를 한 번 줄일 수 있다.
수정한 코드
import java.util.*;
class Solution {
public int[] solution(int[] fees, String[] records) {
TreeMap<String, Integer> totalTimeMap = new TreeMap<>();
for (String record : records) {
String[] splitRecord = record.split(" ");
String time = splitRecord[0];
String carNumber = splitRecord[1];
String contents = splitRecord[2];
int minute = timeCal(time, "23:59");
if (contents.equals("OUT")) {
minute *= -1;
}
totalTimeMap.merge(carNumber, minute, Integer::sum);
}
List<Integer> answer = new ArrayList<>();
List<String> keySet = new ArrayList<>(totalTimeMap.keySet());
for (String key : keySet) {
answer.add(computeFee(fees, totalTimeMap.get(key)));
}
// 결과 리턴
return answer.stream().mapToInt(i->i).toArray();
}
public static int timeCal(String inTime, String outTime) {
String[] splitInTime = inTime.split(":");
String[] splitOutTime = outTime.split(":");
return (Integer.parseInt(splitOutTime[0])*60 + Integer.parseInt(splitOutTime[1]))
- (Integer.parseInt(splitInTime[0])*60 + Integer.parseInt(splitInTime[1]));
}
public static int computeFee(int[] fees, int time) {
// 요금 정리
int basicTime = fees[0];
int basicFee = fees[1];
int unitTime = fees[2];
int unitFee = fees[3];
int totalFee = basicFee;
// 계산
time -= basicTime;
if (time <= 0) return totalFee;
double doubleTime = time;
totalFee += (int) (Math.ceil(doubleTime/unitTime) * unitFee);
return totalFee;
}
}'자료구조 & 알고리즘 > 문제 풀이 (프로그래머스)' 카테고리의 다른 글
| 가장 큰 수 (0) | 2026.06.22 |
|---|---|
| 다리를 지나가는 트럭 (큐) (0) | 2026.06.19 |
| 롤케이크 자르기 (0) | 2026.06.18 |
| 뒤에 있는 큰 수 찾기 (0) | 2026.06.17 |
| k진수에서 소수 개수 구하기 (0) | 2026.06.12 |




