문제
https://school.programmers.co.kr/learn/courses/30/lessons/92341
해설
차량별 주차요금을 차량번호가 작은 순으로 출력하는 문제입니다. 문제의 조건을 잘 보고 사용가능한 자료구조와 분기를 파악하여 구현하면 해결가능합니다.
1. 데이터 정리
문제의 조건을 읽어보면 차량을 총 주차시간을 기준으로 요금을 측정하기 때문에 입력 데이터를 가공하기 쉽도록 String값을 Int배열로 바꾸고 차량번호순 오름차순으로 정렬, 같다면 시간 순으로 정렬하여 값을 변경했습니다.
2. 주차 시간별 요금 정산
이후 각 차량별 총 주차시간을 얻기위해 이전 차량번호와 비교하여 총 주차시간을 초기화하고, 누적하여 모아주다가 해당 입력 데이터가 그 차량에 대해 마지막인 경우 총 주차시간을 요금으로 변경하여 정답 배열에 넣는 방식으로 해결했습니다.
추가코드 변경점
1. 총 주차시간의 계산법 및 Map의 사용
IN 과 OUT의 시간을 -와 +로 계산하여 총 누적 시간을 입력값 처리 구간에서 해결하였습니다.
만약 입력값이 IN1, OUT1, IN2, OUT2, IN3 이라면
총 누적시간은 OUT1 - IN1 + OUT2 - IN2 + 23:59 - IN3으로 계산해야 첫 코드에서는 이를 일일히 계산해 주었지만
입력을 받을 때부터 IN은 -를 붙이도록 하여 Map에 포함해서 입력값 정리 단계에서 총 주차 시간을 계산해 주었습니다.
입력값이 홀수개(IN이 마지막에 하나 더 있는 경우) 에는 누적시간이 음수가되어 23:59만큼 더해주면 되어 더 나은 관점으로 계산이 가능합니다.
이를 통해 배열의 정렬하는 시간을 줄이고 공간복잡도 또한 배열에 비해 map을 통해 더 줄일 수 있어 빠르고 효율적인 코드임을 알았습니다.
코드
import java.util.*;
class Solution {
public int[] solution(int[] fees, String[] records) {
int[] answer = {};
int[][] data = new int[records.length][3];
for(int i=0;i<records.length;i++){
String[] input = records[i].split(" ");
String[] time = input[0].split(":");
data[i][0] = Integer.parseInt(time[0])*60 + Integer.parseInt(time[1]);
data[i][1] = Integer.parseInt(input[1]);
data[i][2] = input[2].equals("IN") ? 0:1;
}
Arrays.sort(data, (o1,o2)->o1[1]==o2[1]?o1[0]-o2[0]:o1[1]-o2[1]);
ArrayList<Integer> al = new ArrayList<>();
int sumTime=0;
int startTime=0;
int lastNum=10000;
for(int i=0;i<data.length;i++){
// 차량번호별 시간 누적
if(lastNum!=data[i][1]){
startTime = data[i][0];
sumTime=0;
lastNum = data[i][1];
}else{
if(data[i][2]==0){
startTime = data[i][0];
}else{
sumTime += data[i][0]-startTime;
}
}
// 마지막요소인경우 누적시간을 요금으로 바꾸어 저장
if(i+1==data.length ||(i+1!=data.length && data[i+1][1]!=data[i][1])){
if(data[i][2]==0) sumTime += 23*60+59 - startTime;
if(sumTime<= fees[0]){
al.add(fees[1]);
}else{
al.add(fees[1] + (int)Math.ceil((sumTime-fees[0])*1.0 / fees[2]) * fees[3]);
}
}
}
answer = al.stream().mapToInt(i->i).toArray();
return answer;
}
}
추가 코드
import java.util.*;
class Solution {
public int timeToInt(String time) {
String temp[] = time.split(":");
return Integer.parseInt(temp[0])*60 + Integer.parseInt(temp[1]);
}
public int[] solution(int[] fees, String[] records) {
TreeMap<String, Integer> map = new TreeMap<>();
for(String record : records) {
String temp[] = record.split(" ");
int time = temp[2].equals("IN") ? -1 : 1;
time *= timeToInt(temp[0]);
map.put(temp[1], map.getOrDefault(temp[1], 0) + time);
}
int idx = 0, ans[] = new int[map.size()];
for(int time : map.values()) {
if(time < 1) time += 1439;
time -= fees[0];
int cost = fees[1];
if(time > 0)
cost += (time%fees[2] == 0 ? time/fees[2] : time/fees[2]+1)*fees[3];
ans[idx++] = cost;
}
return ans;
}
}
'[IT] 코딩테스트 > [문제 및 풀이] 프로그래머스' 카테고리의 다른 글
[프로그래머스] PCCP 기출문제 1번 (붕대 감기) / 자바(Java) (1) | 2024.01.04 |
---|---|
[프로그래머스] PCCP 기출문제 2번 (석유 시추) / 자바(Java) (0) | 2024.01.03 |
[프로그래머스] 두 큐 합 같게 만들기 / 자바(Java) (0) | 2023.11.06 |
[프로그래머스] 푸드 파이트 대회 / 자바(Java) (1) | 2023.11.02 |
[프로그래머스] 성격 유형 검사하기 / 자바(Java) (1) | 2023.11.01 |