중복을 허용하지 않고 <key, value> 쌍으로 데이터를 저장하는 HashMap의 특징을 이용해 풀었다.
전체 코드는 다음과 같다.
import java.util.*;
class Solution {
static int LAST = (23 * 60) + 59;
public int[] solution(int[] fees, String[] records) {
int[] answer;
HashMap<String, Integer> hashMap = new HashMap<>();
Stack<Integer> stack = new Stack<>();
Arrays.sort(records, new Comparator<String>(){
@Override
public int compare(String o1, String o2){
String[] o1a = o1.split(" ");
String[] o2a = o2.split(" ");
return o1a[1].compareTo(o2a[1]);
}
});
String[] start = records[0].split(" ");
String before = start[1];
for(int i = 0; i < records.length; i++){
String[] tmp = records[i].split(" ");
String[] timeString = tmp[0].split(":");
int time = (Integer.parseInt(timeString[0]) * 60) + Integer.parseInt(timeString[1]);
String carNum = tmp[1];
String type = tmp[2];
if(type.equals("IN")){
if(stack.isEmpty()){
stack.add(time);
}else{
int timeStart = stack.pop();
int parkedTime = LAST - timeStart;
int stackedTime = hashMap.getOrDefault(before, 0);
hashMap.put(before, stackedTime + parkedTime);
stack.add(time);
}
}else if(type.equals("OUT")){
int timeStart = stack.pop();
int parkedTime = time - timeStart;
int stackedTime = hashMap.getOrDefault(carNum, 0);
hashMap.put(carNum, stackedTime + parkedTime);
}
before = carNum;
}
if(!stack.isEmpty()){
int timeStart = stack.pop();
int parkedTime = LAST - timeStart;
int stackedTime = hashMap.getOrDefault(before, 0);
hashMap.put(before, stackedTime + parkedTime);
}
answer = new int[hashMap.size()];
ArrayList<String> arrayList = new ArrayList<>(hashMap.keySet());
Collections.sort(arrayList);
for(int i = 0; i < arrayList.size(); i++){
String key = arrayList.get(i);
int time = hashMap.get(key);
int fee = 0;
time -= fees[0];
fee += fees[1];
if(time > 0){
double exceedTime = time / (double)fees[2];
int exceedFee = (int)Math.ceil(exceedTime) * fees[3];
fee += exceedFee;
}
answer[i] = fee;
}
return answer;
}
}
출차된 내역이 없다면 출차된 것으로 간주할 시간인 LAST와
차량의 번호를 key로, 총 주차 시간을 value로 저장하는 HashMap,
차량이 주차를 시작한 시간을 저장할 Stack을 만들었다.
class Solution {
static int LAST = (23 * 60) + 59;
public int[] solution(int[] fees, String[] records) {
int[] answer;
HashMap<String, Integer> hashMap = new HashMap<>();
Stack<Integer> stack = new Stack<>();
차량의 주차 시간을 계산할 때 여러 차량을 동시에 계산하는 것 보다 한 차량마다 계산하는 것이 더 편하기에records 배열을 같은 차량 번호끼리 뭉치도록 정렬하였다.
"주차시간 차량번호 내역" 형식으로 저장된 문자열 records를 차량번호 기준으로 오름차순 정렬시켰다.
Arrays.sort(records, new Comparator<String>(){
@Override
public int compare(String o1, String o2){
String[] o1a = o1.split(" ");
String[] o2a = o2.split(" ");
return o1a[1].compareTo(o2a[1]);
}
});
현재 보는 차량의 이전 차량을 저장하는 before을 첫 번째 차량으로 초기화했다.
String[] start = records[0].split(" ");
String before = start[1];
records의 길이만큼 아래 내용을 반복한다.
for(int i = 0; i < records.length; i++){
...
}
records에서 기록을 하나씩 가져와
시간, 차량번호, 기록을 저장한다.
이 때 시간은 분단위로 저장한다.
for(int i = 0; i < records.length; i++){
String[] tmp = records[i].split(" ");
String[] timeString = tmp[0].split(":");
int time = (Integer.parseInt(timeString[0]) * 60) + Integer.parseInt(timeString[1]);
String carNum = tmp[1];
String type = tmp[2];
...
}
기록을 확인해 주차인지 출차인지 확인한다.
if(type.equals("IN")){
...
}else if(type.equals("OUT")){
...
}
만약 주차라면 지금 stack에 주차된 차가 있는지 확인한다.
주차된 차량이 있다는 것은 이전 차량이 주차한 채로 끝났다는 것이다.
출차된 내역이 없다면 LAST를 출차한 시간으로 간주하므로 stack에서 주차한 시간을 가져와 LAST에 그 수를 빼 주차한 시간을 계산한다.
그 후 before로 이전 차량의 번호를 얻어 HashMap의 key값으로 검색해 누적 주차 시간을 얻고,
이전 차량의 누적 주차 시간에 지금 계산한 주차 시간을 더한 값을HashMap에 넣는다.
그 후 빈 stack에 지금 차량의 주차한 시간을 집어넣는다.
만약 주차된 차량이 없다면 바로 지금 차량의 주차한 시간을 집어넣는다.
if(type.equals("IN")){
if(stack.isEmpty()){
stack.add(time);
}else{
int timeStart = stack.pop();
int parkedTime = LAST - timeStart;
int stackedTime = hashMap.getOrDefault(before, 0);
hashMap.put(before, stackedTime + parkedTime);
stack.add(time);
}
}else if(type.equals("OUT")){
...
}
만약 출차라면
stack에 저장되어있는 주차 시작 시간을 출차 시간에서 뺀다.
그 후 HashMap의 key값으로 검색해 누적 주차 시간을 얻고,
누적 주차 시간에 지금 계산한 주차 시간을 더한 값을HashMap에 넣는다.
if(type.equals("IN")){
...
}
}else if(type.equals("OUT")){
int timeStart = stack.pop();
int parkedTime = time - timeStart;
int stackedTime = hashMap.getOrDefault(carNum, 0);
hashMap.put(carNum, stackedTime + parkedTime);
}
계산 후엔 이전 차량 값을 현재 차량 값으로 바꿔준다.
for(int i = 0; i < records.length; i++){
...
before = carNum;
}
반복문이 끝난 후에 stack이 비어있는지 확인한다.
만약 비어있지 않다면 마지막 차량이 출차하지 않은 채로 끝났다는 뜻이므로
LAST에 출차한것으로 간주해 계산한다.
if(!stack.isEmpty()){
int timeStart = stack.pop();
int parkedTime = LAST - timeStart;
int stackedTime = hashMap.getOrDefault(before, 0);
hashMap.put(before, stackedTime + parkedTime);
}
정답 배열의 크기를 차량 수인 HashMap의 크기로 초기화한다.
ArrayList를 만들어 HashMap의 key값을 저장하고, 오름차순으로 정렬한다.
answer = new int[hashMap.size()];
ArrayList<String> arrayList = new ArrayList<>(hashMap.keySet());
Collections.sort(arrayList);
ArrayList의 크기만큼 반복하며 오름차순으로 정렬된 차량 번호를 하나씩 가져온다.
차량 번호로 HashMap에 저장되있는 차량의 총 주차 시간을 가져오고
fees배열에 저장되있는 주차 요금에 따라서 주차 요금을 계산해 정답 배열에 넣어준다.
for(int i = 0; i < arrayList.size(); i++){
String key = arrayList.get(i);
int time = hashMap.get(key);
int fee = 0;
time -= fees[0];
fee += fees[1];
if(time > 0){
double exceedTime = time / (double)fees[2];
int exceedFee = (int)Math.ceil(exceedTime) * fees[3];
fee += exceedFee;
}
answer[i] = fee;
}
return answer;