티스토리 뷰

 

2022 KAKAO BLIND RECRUITMENT 주차요금 계산 Lv.2

 

코딩테스트 연습 | 프로그래머스 스쿨

개발자 취업의 필수 관문 코딩테스트를 철저하게 연습하고 대비할 수 있는 문제를 총망라! 프로그래머스에서 선발한 문제로 유형을 파악하고 실력을 업그레이드해 보세요!

school.programmers.co.kr


 

🔒 문제

주차 요금을 나타내는 정수 배열 fees, 자동차의 입/출차 내역을 나타내는 문자열 배열 records가 매개변수로 주어집니다. 차량 번호가 작은 자동차부터 청구할 주차 요금을 차례대로 정수 배열에 담아서 return 하도록 solution 함수를 완성해 주세요.

 

🔎  풀이

알고리즘 자체는 단순하지만 데이터를 가공하는 과정에서 배울 점이 많아서 정리해보고자 한다.

 

우선 로직은 다음과 같이 구성했다.

[1] records 배열을 돌며 다음 두 가지 조건문 중 하나 수행
     - 입차 기록이면 entryRecord맵에 <차량 번호, 입차 시간> 삽입하기
     - 출차 기록이면 map에서 입차 기록 찾아서 총 주차 시간 계산 함수 getParkingTime 호출, 맵에서 입차 기록 삭제 
[2] records 배열을 모두 돌고 entryRecord 맵에 남아있는 요소들은 출차 시간을 23:59로 설정하고 getParkingTime 호출
[3] ArrayList 'getParkingTime'을 2차원 배열로 전환한 뒤 자동차 번호가 작은 순으로 배열
[4] 주차 요금 계산해서 answer return

 

문제 지문에서 answer를 리턴할 때 차량번호가 오름차순으로 주차요금만 담아서 정수 배열에 담아 보내라고 주어졌다

그렇기 때문에 나는 무작위로 담겨있는 totalTime 2차원 ArrayList를 어떻게 차번호 순서로 정렬해야 할지 고민이 많았다.

만약 1차원 ArrayList라면 Collentions.sort()를 사용해서 쉽게 정렬할 수 있지만 2차원이기 때문에 sort를 사용할 수 없었다.

그래서 내가 생각한 방법은 2차원 ArrayList를 2차원 배열로 전환하고, 2차원 배열을 Comparator를 사용해 정렬하는 방식이다.

 

1. ArrayList -> 배열 전환하는 방법

	int[][] array = new int[totalTime.size()][2];
        for( int i = 0; i < totalTime.size(); i++ ){
            array[i][0] = totalTime.get(i).get(0);
            array[i][1] = totalTime.get(i).get(1);
            System.out.println( array[i][0] + ": " +array[i][1]);
        }

 

2. 2차원 배열 정렬하는 방법

배열을 정렬할 때 사용하는 Arrays.sort()에 바로 2차원 배열을 담아 정렬하려고 하면 비교 기준이 명확하지 않으므로 오류가 발생한다. 그래서 Comparable, Comparator 인터페이스를 구현해 정렬기준을 정해줘야 한다. 나는 Comparator.comparingInt()을 사용해서 사전순 정렬을 구현했다.

Arrays.sort(array, Comparator.comparingInt((int[] o) -> o[0])); // 첫번째 숫자 (차량 번호 오름차순)

 

나는 차량 번호를 array [i][0]에 저장했기 때문에 위와 같이 Comparator 정렬기준을 첫 번째 인덱스를 기준 오름차순으로 설정했는데 내림차순이나 첫 번째 인덱스 기준이 아닌 두 번째 인덱스 기준 오름차순, 내림차순을 구현하려면 다음과 같이 설정하면 된다. 

Arrays.sort(array, Comparator.comparingInt((int[] o) -> o[0]).reversed()); // 첫번째 숫자 기준 내림차순 
Arrays.sort(array, Comparator.comparingInt((int[] o) -> o[1]));            // 두번째 숫자 기준 오름차순
Arrays.sort(array, Comparator.comparingInt((int[] o) -> o[1]).reversed()); // 두번째 숫자 기준 내림차순

 


 

🔐 전체 코드

import java.util.*;

class Solution {

    Map<String, String> entryRecord = new HashMap<>(); // 입차 기록 저장 <차량번호, 입차시간>
    ArrayList<ArrayList<Integer>> totalTime = new ArrayList<>(); // 주차 시간 저장 <차량 번호, 주차 시간>

    public int[] solution(int[] fees, String[] records) {

        for( int i = 0; i < records.length; i++ ){
            String[] record = records[i].split(" ");

            if( record[2].equals("IN")){
                entryRecord.put(record[1], record[0]); // 입차 기록하기
            }
            else if( record[2].equals("OUT")){         // 출차 기록
                String[] entryTime = entryRecord.get(record[1]).split(":"); // 입차 시간 가져오기
                String[] exitTime = record[0].split(":");
                entryRecord.remove(record[1]); // 출차 했으니 입차 기록에서 삭제

                getParkingTime( Integer.parseInt( record[1]),entryTime, exitTime, fees);
            }
        }

        for( String key : entryRecord.keySet() ){ // 출차 기록이 없는 차량들
            String[] entryTime = entryRecord.get(key).split(":"); // 입차 시간 가져오기
            String[] exitTime = new String[]{"23", "59"};

            getParkingTime( Integer.parseInt(key),entryTime, exitTime, fees );
        }

        // 차량순 정렬
        int[][] array = new int[totalTime.size()][2];
        for( int i = 0; i < totalTime.size(); i++ ){
            array[i][0] = totalTime.get(i).get(0);
            array[i][1] = totalTime.get(i).get(1);
        }

        Arrays.sort(array, Comparator.comparingInt((int[] o) -> o[0]));

        int[] answer = new int[array.length];

        for( int i = 0; i < array.length; i++ ){
            answer[i] = getParkingFee( array[i][0], array[i][1], fees );
        }

        return answer;
    }

    public void getParkingTime( int car, String[] inTime, String[] outTime, int[] fees ){
        int hours = Integer.parseInt(outTime[0]) - Integer.parseInt(inTime[0]);
        int minutes = Integer.parseInt(outTime[1]) - Integer.parseInt(inTime[1]);

        if( minutes < 0 ){
            hours -- ;
            minutes += 60;
        }
        minutes += ( hours * 60 );

        // 이미 주차요금 기록이 있으면 누적시키기
        boolean find = false;
        for( ArrayList<Integer> list : totalTime ){
            if(list.get(0) == car){
                int time = list.get(1);
                list.set(1,time + minutes);
                find = true;
            }
        }
        if(!find){ // 없다면 새로 넣기
            ArrayList<Integer> array = new ArrayList<>();
            array.add(car);      // 차량 번호
            array.add(minutes); // 계산된 주차 요금
            totalTime.add(array);
        }
    }

    public int getParkingFee( int car, int minutes, int[] fees ){
        int totalFee = 0 ;

        // 주차 요금 계산
        minutes -= fees[0];
        totalFee += fees[1];

        if( minutes > 0 ){
            totalFee += ( fees[3] * ( minutes / fees[2] ));
            if( minutes % fees[2] > 0) totalFee += fees[3];
        }
        return totalFee;
    }
}

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함