프로그래머스 Level3

남기현·2022년 3월 10일
0

프로그래머스

목록 보기
3/3
post-thumbnail

✅ 셔틀버스

문제링크

📌 문제설명

요약
사무실에 늦지 않으며 가장 늦은 시간에 탈 수 있는 셔틀버스 시간을 구하라

📌 문제풀이

😺GitHub 바로가기

▪ timetable의 시간을 모두 분으로 바꿔주기
▪ 대기열의 시간을 빠른 순서대로 정렬하기
▪ n, t, m에 따라 버스에 대기 크루들을 탑승시키기
▪ 버스에 정원이 찼을 때와 그렇지 않을 경우로 나눠 최종 탑승 시간 추출

import java.util.Arrays;
import java.util.Stack; 
 
class Solution {
    public String solution(int n, int t, int m, String[] timetable) {

        String answer = "";
        
        //timetable MM 바꾸기
        int[] arr = new int[timetable.length];
        
        for(int i=0; i<timetable.length; i++){            
            int timeMM = Integer.parseInt(timetable[i].substring(0,2))*60;
            int timeSS = Integer.parseInt(timetable[i].substring(3,5));                        
            
            arr[i] = timeMM+timeSS;    
        }
        
        //정렬
        Arrays.sort(arr);
        
        //timetable배열 스택에 넣기
        Stack<Integer> standTime = new Stack<>(); 
        
        for(int j=0; j<arr.length; j++){
            standTime.push(arr[j]);
        }
        
        int busTime = 540;
        
        //버스에 탑승될 크루 스택
        Stack<Integer> busCount = new Stack<>(); 

        int timeMM = 0;
        
        for(int k=0; k<n; k++){
            
            //버스 초기화(회차마다 새 버스이므로)
            busCount.clear();
            
            for(int l=0; l<standTime.size(); l++){
                
                if(busTime>=standTime.elementAt(l)){
                    
                    //자리있으면 태우기
                    if(busCount.size()<m && (standTime.elementAt(l) != 0) ){
                        
                        busCount.push(standTime.elementAt(l));
                        //standTime.remove(l);   
                        standTime.set(l, 0);
                        
                    }  
                    
                }       
            }    
            
            if(busCount.size()==m){    
                        
                //마지막 탑승자보다 1분 빠르게 오기
                timeMM = busCount.elementAt(busCount.size()-1)-1;

            //정원이 아닐때    
            }else{

                //버스 도착시간에 오기
                timeMM = busTime;

            }

            busTime += t;
            
        }
        
        //시간바꾸기 ex) 09:12
        if(Integer.toString(timeMM/60).length() == 1){
            answer += "0";
            answer += Integer.toString(timeMM/60);
        }else{
            answer += Integer.toString(timeMM/60);
        }

        answer += ":";

        if(Integer.toString(timeMM%60).length() == 1){
            answer += "0";
            answer += Integer.toString(timeMM%60);
        }else{
            answer += Integer.toString(timeMM%60);
        }

        return answer;
    }
}

📌 부족했던점

문제1
크루들이 버스를 탑승하면 스택에서 remove를 통해 크루들을 지워버렸는데 그렇게 될 경우 스택의 사이즈가 바뀌게 되고 처음 생각했던 for 문의 개수가 아닌 remove되어 줄어든 스택 사이즈만큼 for 문을 돌게 되어 대기 중인 크루를 건너뛰는 현상이 발생했다..🤦‍♂️

(그림1 예시)예를 들어 for 문을 통해 0 index부터 스택 사이즈(10)까지 반복문을 돌릴 때 첫 번째 반복문에서 remove를 하게 되면 0인덱스가 사라지게 되고 1인덱스가 당겨져서 0인덱스가 되는데 이럴 경우 다음 반복문은 1부터 시작하는데 검사해야 할 1인덱스는 0인덱스로 당겨졌기 때문에 1인덱스였던 크루는 건너뛰게 되는 것이다.

[그림1]

해결1
remove 타이밍이 잘못된 줄 알았지만 remove 자체가 잘못된 것이었다..❗❗ 그래서 set 함수를 통해 삭제가 아닌 0으로 치환을 선택하였다.(시간은 00:01~11:59이기 때문에 0이 나올 수 없음)

문제2
처음 if 문을 시작할 때 예를 들어 버스가 9시에 올 경우 9시보다 일찍 온 크루들을 태웠는데 9시보다 큰 시간이거나 전날 버스를 탑승하지 못한 크루들은 하루가 지나면 리셋되어 버스를 탑승할 수 없기에 분기문을 하나 더 작성해야 했다.

if(busCount.size()==m){    

	//마지막 탑승자보다 1분 빠르게 오기
	timeMM = busCount.elementAt(busCount.size()-1)-1;

//정원이 아닐때    
}else{

	//버스 도착시간에 오기
	timeMM = busTime;

}

해결2
위와 같이 시간을 정해주는 로직을 else 문을 추가하여 작성해도 되지만 중복 코드로 인해 코드가 깔끔해 보이지 않아서 밖으로 빼는 초이스를 하였다.

📌 결과

👍👍👍
profile
내가 보려고 만든 velog

0개의 댓글