카테고리
알고리즘
나만의 카테고리
알고리즘
문제 링크
https://school.programmers.co.kr/learn/courses/30/lessons/92341
요점
- 알맞은 로직 짜기
- 적당한 자료 구조 사용
- for문으로 iteration에 사용되는 객체를 for문 안에서 제거하지 않도록 주의 (런타임 에러)
참고 지식
- Map, Set
- Map Sort 하기
풀이 (Java)
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.time.format.DateTimeFormatter;
class Solution {
Map<String, LocalDateTime> inCarMap = new HashMap<>();
Map<String, Integer> accumCarMap = new HashMap<>();
Map<String, Integer> carFeeMap = new HashMap<>();
int baseTime = 0;
int baseFee = 0;
int perTime = 0;
int perFee = 0;
public int[] solution(int[] fees, String[] records) {
// 기본 가격 세팅
setBaseFee(fees);
// 기본 시간 계산
for (String record : records) {
String[] sptRecords = record.split(" ");
if (sptRecords[2].equals("IN")) {
inCar(sptRecords[1], sptRecords[0]);
} else if (sptRecords[2].equals("OUT")) {
outCar(sptRecords[1], sptRecords[0]);
}
}
// 23:59 출차 차량 시간 계산
calLastOutCarFee();
// 요금 계산
calFee();
// 번호 작은 차량 순서로 정렬된 결과
int[] answer = sortByCarNumber();
return answer;
}
public void setBaseFee(int[] fees) {
baseTime = fees[0];
baseFee = fees[1];
perTime = fees[2];
perFee = fees[3];
}
public void inCar(String carNumber, String time) {
LocalDateTime lTime = LocalDateTime.parse("2022-01-01 " + time, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
inCarMap.put(carNumber, lTime);
}
public void outCar(String carNumber, String time) {
LocalDateTime lTime = LocalDateTime.parse("2022-01-01 " + time, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
int defTime = (int)ChronoUnit.MINUTES.between(inCarMap.get(carNumber), lTime);
accumCarMap.put(carNumber, Optional.ofNullable(accumCarMap.get(carNumber)).orElse(0) + defTime);
inCarMap.remove(carNumber);
}
public void calLastOutCarFee() {
Set<Map.Entry<String, LocalDateTime>> tempSet = new HashSet<>();
tempSet.addAll(inCarMap.entrySet());
for (Map.Entry<String, LocalDateTime> each : tempSet) {
outCar(each.getKey(), "23:59");
}
}
public void calFee() {
for (Map.Entry<String, Integer> each : accumCarMap.entrySet()) {
int defTime = each.getValue();
int fee = baseFee;
if (defTime > baseTime) {
int rest = ((defTime - baseTime) % perTime) > 0 ? 1 : 0;
fee = fee + (int)(((defTime - baseTime) / perTime + rest) * perFee);
}
carFeeMap.put(each.getKey(), fee);
}
}
public int[] sortByCarNumber() {
List<Map.Entry<String, Integer>> feeEntries = new LinkedList<>(carFeeMap.entrySet());
Collections.sort(feeEntries, (o1, o2) -> o1.getKey().compareTo(o2.getKey()));
int[] result = new int[feeEntries.size()];
for (int i = 0; i < feeEntries.size(); i++) {
result[i] = feeEntries.get(i).getValue();
}
return result;
}
}
이 문제는 특별한 기법을 적용해야 한다기 보다는 그냥 로직을 알맞게 짤 수 있는지를 확인하는 문제인 것 같습니다.
시간 단축을 위해 좀 어지럽게 풀긴 했지만 위와 같이 main에서 각각 함수로 나누어서 작성하면 나중에 에러가 발생했을 때 주석처리하며 에러를 찾기가 쉬워집니다.
프로그래머스의 문제 질문하기의 글 중에 있는 주의점으로는 Map을 사용해서 풀 경우 for문에서 사용되는 객체를 for문 안에서 건드리는 로직이 불가피한 것 같습니다. 이를 주의하지 않으면 몇몇 테스트 케이스에서 런타임 에러가 발생합니다.
알고리즘 초보가 정리한 글입니다
더 좋은 방법이나 코드에 대한 코멘트 언제나 환영합니다!
반응형
'Algorithm > Algorithm Test' 카테고리의 다른 글
[프로그래머스] N으로 표현 (C++, Java) (0) | 2022.05.06 |
---|---|
[프로그래머스] n진수 게임 (Java) (0) | 2021.07.29 |
[프로그래머스] 후보키 (0) | 2021.07.15 |
[프로그래머스] 방금그곡 (Java) (0) | 2021.06.23 |
[프로그래머스] 프렌즈4블록 (Java) (0) | 2021.06.08 |