티스토리 뷰
과제 진행하기
import java.util.*;
import java.util.stream.*;
class Solution {
public String[] solution(String[][] plansArr) {
Plan[] plans = new Plan[plansArr.length];
for(int i = 0; i < plansArr.length; i++) {
plans[i] = new Plan(plansArr[i]);
}
Arrays.sort(plans, (a, b) -> a.start - b.start);
Stack<Plan> stop = new Stack<>();
List<String> answer = new ArrayList<>();
for(int i = 0; i < plans.length - 1; i++) {
Plan curPlan = plans[i];
Plan nextPlan = plans[i + 1];
if(curPlan.getEndTime() > nextPlan.start) {
curPlan.playTime = curPlan.getEndTime() - nextPlan.start;
stop.push(curPlan);
continue;
}
answer.add(curPlan.name);
int restTime = nextPlan.start - curPlan.getEndTime();
System.out.println(restTime);
while(restTime > 0 && !stop.isEmpty()) {
Plan stoppedPlan = stop.peek();
int timeDiff = stoppedPlan.playTime - restTime;
stoppedPlan.playTime = timeDiff;
restTime = timeDiff * -1;
if(timeDiff > 0) break;
answer.add(stop.pop().name);
}
}
answer.add(plans[plans.length - 1].name); // 마지막 index의 plan 처리
while(!stop.isEmpty()) answer.add(stop.pop().name); // stack에 남아있던 plan들 넣기
return answer.toArray(new String[answer.size()]);
}
}
class Plan {
String name;
int start;
int playTime;
public Plan(String name, String start, String playTime) {
this.name = name;
String[] time = start.split(":");
this.start = Integer.parseInt(time[0]) * 60 + Integer.parseInt(time[1]); // 시간 * 60 + 분
this.playTime = Integer.parseInt(playTime);
}
public Plan(String[] plan) {
this(plan[0], plan[1], plan[2]);
}
public int getEndTime() {
return start + playTime;
}
}
풀이 설명
- Plan 객체를 생성해서 배열에 넣는다.
- 배열을 정렬한다.
- 배열을 plan의 마지막 전 인덱스까지 순회한다.
- 현재 plan의 종료 시간이 다음 plan의 시작 시간 이후일 경우
- 현재 plan의 playTime을 종료시간과의 차이만큼 빼고 stack에 넣는다.
- 그 외
- answer에 현재 plan 이름을 넣는다.
- 다음 plan 시작 시간까지의 여유 시간있을 동안 && stack 빌 때까지 반복한다.
- stack에서 요소를 빼서 남은 시간과 비교하여 처리해주면 된다.
- 현재 plan의 종료 시간이 다음 plan의 시작 시간 이후일 경우
- 마지막 인덱스 plan와 stack에 남은 plan들을 answer에 넣고 출력한다.
실수
위의 정답 코드
while(restTime > 0 && !stop.isEmpty()) {
Plan stoppedPlan = stop.peek();
int timeDiff = stoppedPlan.playTime - restTime;
stoppedPlan.playTime = timeDiff;
restTime = timeDiff * -1;
if(timeDiff > 0) break;
answer.add(stop.pop().name);
}
틀렸던 코드
while(restTime > 0 && !stop.isEmpty()) {
Plan stoppedPlan = stop.peek();
stoppedPlan.playTime -= restTime;
restTime -= stoppedPlan.playTime;
if(stoppedPlan.playTime - restTime > 0) break;
answer.add(stop.pop().name);
}
틀린 코드의 원인은 if(stoppedPlan.playTime - restTime > 0) break;
의 시점이다.
이미 stoppedPlan.playTime도 restTime도 값이 달라졌기 때문에 원하던 값과 달라진다.
if문을 줄이다보니 어느 순간 이렇게 되있었는데 찾는데 한참 걸렸다..
어이없는 실수들을 줄여야지만 푸는 시간을 절약할 수 있을 것 같다.
아직은 레벨2 문제를 푸는데 시간이 너무 오래 걸린다.
처음에는 LocalTime으로 바꿔서 풀었었는데, 나쁘지는 않았지만 모르는 메소드가 너무 많아 실제 코테에서 사용하려면 공식문서가 지원이 되야할 것 같다. 그래서 다른 방법을 찾다가 연산할 때 편하게 (시간 * 60 + 분) 한 값을 start로 두는 아이디어를 아래 링크에서 얻었다.
아이디어 얻은 블로그
'알고리즘 > Programmers' 카테고리의 다른 글
[Level2] 광물 캐기 (JAVA) (0) | 2023.04.22 |
---|---|
[Level2] 무인도 여행 (JAVA) (0) | 2023.04.20 |
[Level2] 두 원 사이의 정수 쌍 (JAVA) (0) | 2023.04.17 |
[Level1] 성격 유형 검사하기 (JAVA) (0) | 2023.04.09 |
[Level1] 달리기 경주 문제 풀이 (JAVA) (0) | 2023.04.09 |
댓글