✔문제링크
요약
사무실에 늦지 않으며 가장 늦은 시간에 탈 수 있는 셔틀버스 시간을 구하라
▪ 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 문을 추가하여 작성해도 되지만 중복 코드로 인해 코드가 깔끔해 보이지 않아서 밖으로 빼는 초이스를 하였다.