본문 바로가기

[IT] 코딩테스트/[문제 및 풀이] 프로그래머스

[프로그래머스] 주차 요금 계산 / 자바(Java)

728x90

문제

https://school.programmers.co.kr/learn/courses/30/lessons/92341

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 


해설

차량별 주차요금을 차량번호가 작은 순으로 출력하는 문제입니다. 문제의 조건을 잘 보고 사용가능한 자료구조와 분기를 파악하여 구현하면 해결가능합니다.

 

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;
    }
}
728x90