https://school.programmers.co.kr/learn/courses/30/lessons/92341?language=java# 

 

프로그래머스

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

programmers.co.kr

문제 풀이 (JAVA)

import java.util.*;
import java.text.*;
//초 : 1000 
//분 : (1000 * 60)
//시 : (1000 * 60 * 60)
class Solution {
    public int[] solution(int[] fees, String[] records) throws ParseException{
        int[] answer = {};
        HashMap<String,String> timeMap = new HashMap<>(); // 차량의 부분 누적 시간
        HashMap<String,Long> resultMap = new HashMap<>(); // 차량의 총 누적 시간
        TreeSet<String> set = new TreeSet<>(); // 순서를 저장할 변수
        SimpleDateFormat formatter = new SimpleDateFormat("HH:mm"); // 날짜 포맷 형식 선언
        for(int i=0; i<records.length; i++){
            String [] str = records[i].split(" ");
            String time = str[0]; // 입/출차 시각
            String carNum = str[1]; // 차량 번호
            String info = str[2]; // 입차/출차
            if(timeMap.containsKey(carNum) != true && "IN".equals(info) == true){
                // 입차시 차량번호의 시간 정보 저장
                timeMap.put(carNum,time);
            }
            if(timeMap.containsKey(carNum) == true && "OUT".equals(info) == true){
                // 출차시 입차시간 정보를 가져와 누적시간을 계산한다.
                String inTime = timeMap.get(carNum); // 입차시간
                Date date1 = formatter.parse(inTime); 
                Date date2 = formatter.parse(time); // 출차시간
                long stay = (date2.getTime() - date1.getTime())/60000; // 출차시간-입차시간(분)
                if(resultMap.containsKey(carNum) == true){
                    //총 누적시간이 이미 해시맵에 존재한다면, 이전누적시간 + 현재누적시간 저장
                    long beforeTime = resultMap.get(carNum);
                    resultMap.put(carNum,beforeTime+stay);
                }else{
                    // 총 누적시간이 존재하지 않는다면, 최초 누적 입력
                    resultMap.put(carNum,stay);
                }
                set.add(carNum); // 출차시 순서정보 최초 저장, 중복을 허용하지 않음.
                timeMap.remove(carNum); // 입차시간이 저장된 해시맵 KEY를 제거한다.(재입차시를 고려)
            }
        }
        // 입차시간이 저장된 해시맵이 모두 제거되지 않았다면 출차하지 않은 차량이 있는것으로 출차 처리 로직
        if(timeMap.size() > 0){
            for(String key : timeMap.keySet()){
                Date date2 = formatter.parse("23:59"); // 출차 시간 = 23:59
                Date date1 = formatter.parse(timeMap.get(key)); // 입차 시간
                long stay = (date2.getTime() - date1.getTime())/60000; 
                if(resultMap.containsKey(key) == true){
                    long beforeTime = resultMap.get(key);
                    resultMap.put(key,beforeTime+stay);
                }else{
                    resultMap.put(key,stay);
                }
                set.add(key); // 차량 순서 정보 저장(최초 출차)
            }
        }
        answer = new int[resultMap.size()]; // 출력 배열 사이즈 선언
        int i=0;        
        for(String seq : set){
            for(String key : resultMap.keySet()){
                if(seq.equals(key)){ // 순서정보로 반복하여 저장
                    long totalTime = resultMap.get(key); // 총 누적 시간
                    long time = (totalTime-fees[0]); // 초과 시간 계산
                    if(time <= 0){ // 초과시간을 넘지 않았다면 기본 값
                        answer[i++] =(int)fees[1];
                    }else{ // 초과시간을 넘었을시 계산 값
                        // 단위시간으로 나눈 값이 0으로 나누어 떨어지지 않는다면 시간+단위시간/단위시간
                        time = time % fees[2] != 0 ? (time + fees[2])/fees[2] : time/fees[2];
                        answer[i++] =(int) (fees[1] + (time * fees[3])); // 내야할 요금 계산
                    }
                }
            }            
        }
        return answer;
    }
}

 

주요 핵심 포인트

1. 입차시 차량의 시간 정보를 timeMap, 출차시 차량의 누적 시간 정보를 resultMap 해시맵 변수에 저장하였다.

2. 출차시 timeMap에는 이미 입차시각이 저장되어 있으므로, timeMap에 저장된 입차 시간 정보와 출차시 시간 정보를 계산하여 resultMap 해시맵 변수에 누적 시간을 저장하였다.

3. resultMap 해시맵에 차량번호 정보가 이미 존재한다면, 부분 누적 시간이 저장되어 있는 것으로 resultMap의 누적 시간 정보를 갱신한다. 해시맵에 정보가 존재하지 않는다면, 최초로 누적시간이 저장되므로 계산된 정보를 그대로 저장한다.

4. 출차시 순서가 유지되며 중복을 허용하지 않는 TreeSet의 set 변수에 값을 저장할시, 최초 출차시에만 차량번호 정보가 저장된다.

5. 모든 record를 처리하고 timeMap 해시맵 정보가 존재한다면, 출차를 하지 않은 차량이므로 출차 시각 23:59분으로 누적 시간을 계산한다.

6. 순서정보를 저장한 set 순서대로 출력값을 계산한다.

7.  초과시간 time이 0보다 같거나 작다면 시간을 초과하지 않았으므로 기본값을 세팅한다. time > 0 이라면 초과 단위시간을 계산한다.

8. 초과시간이 단위시간으로 나누어 떨어지지 않는다면 (초과시간+단위시간)/단위시간 으로 계산하고, 단위시간으로 나누어 떨어진다면 초과시간/단위시간 으로 계산한다.

 

개선해야할 사항

: 이 문제에서는 필자는 시간을 계산하기 위해 SimpleDateFormat을 선언하였다. 시간 정보를 계산하기 위하여 포맷으로 변환하여 날짜형식으로 변환하였는데, 다른 사람의 풀이 정보를 보았을 때, 시(HH) 정보를 * 60 하여 분 정보로 변환하여 저장하였다. 시간 계산을 위하여 라이브러리를 참조하는것보다 시 정보를 분으로 변환하는 방법이 더 좋은것으로 보인다.

순서정보를 저장하지 못하여 set 변수를 만들었는데, 다른 사람의 풀이를 본 결과 LinkedHashMap으로 선언하여 푼 정보를 보았다. set을 선언할 필요 없이 LinkedHashMap으로 한번 더 풀어봐야겠다.

'프로그래머스(JAVA)' 카테고리의 다른 글

K번째 수  (0) 2022.07.18
구명 보트  (0) 2022.07.16
문자열 압축  (0) 2022.07.09
영어 끝말잇기  (0) 2022.07.07
짝지어 제거하기  (0) 2022.07.05

+ Recent posts