https://school.programmers.co.kr/learn/courses/30/lessons/176962
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
📌- 풀이 및 코드
일단 문제를 봤을 때 , 우선순위 큐와 스택을 사용해서 풀면되겠다라는 생각이 들었지만, 여러 조건문들을 쓰다보니 헷갈려서 꽤 오랜시간 풀었다.
그렇게 어렵지 않은 문제인데 너무 시간을 많이 쓴 것 같아서 어떤 점이 문제였나 복기를 다시 해보니
처음 문제를 풀 때 의사코드를 적당히 작성하고 시작해서 헷갈리는 부분이 발생했을 때 더 오래 걸렸다고 생각함.
이건 어떤 프로그램이든 설계할 때 비슷한 문제를 초래할 것 같다는 생각이 들어서 앞으로 문제를 풀 때도 처음 설계를 제대로 하고 넘어가야겠음.
import java.util.*;
class Work{
String name;
int time;
int extra;
Work(String name ,String time, String extra){ // work 생성시 값들 셋팅해줌
this.name = name;
String[] timeSpl = time.split(":");
int hour = Integer.parseInt(timeSpl[0]) * 60;
int min = Integer.parseInt(timeSpl[1]);
this.time = hour + min;
this.extra = Integer.parseInt(extra);
}
public void cul(int extra2){ // 해당 값의 extra값 수정
this.extra -= extra2;
}
}
class Solution {
public String[] solution(String[][] plans) {
int N = plans.length;
String[] answer = new String[N];
// 우선순위 큐 time 순으로 오름차순 정렬
PriorityQueue<Work> pq = new PriorityQueue<>(new Comparator<Work>(){
@Override
public int compare(Work o1, Work o2){
return o1.time > o2.time ? 1 : -1;
}
});
// 우선순위 큐에 삽입
for(String[] arr: plans){
Work a = new Work(arr[0],arr[1],arr[2]);
pq.add(a);
}
Stack<Work> stack = new Stack<>();
int count =0; // 결과 배열에 넣을 순서 정하기
while(!pq.isEmpty()){
Work cur = pq.poll();
String curName = cur.name;
int curStart = cur.time;
int curPlaytime = cur.extra;
int curTime = curStart;
if(!pq.isEmpty()){ //만약 cur의 값과 비교할 다음 값이 있으면
Work next = pq.peek();
if(curTime + curPlaytime < next.time) { // 시작시간과 사용시간 합친 값이 다음 값의 시작시간보다 작을 경우
answer[count] = curName;
count++;
curTime += curPlaytime;
while(!stack.isEmpty()) { // stack이 빌 때까지
Work rem = stack.pop();
if(curTime + rem.extra <= next.time) { // 현재 시간 + stack 최상단의 남은시간보다 다음 시작시간이 더 크거나 같으면 rem 종료
curTime += rem.extra;
answer[count] = rem.name;
count++;
continue;
}
else { // 아니라면 rem의 extra 시간을 줄여서 다시 stack에 push
rem.cul(next.time - curTime);
stack.push(rem);
break;
}
}
}
else if(curStart + curPlaytime == next.time) { // 시작시간과 사용시간 합친 값이 다음 값의 시작시간과 같을 때 answer에 추가
answer[count] = curName;
count++;
continue;
}
else {
cur.cul(next.time - curTime);
stack.push(cur);
}
} else { // 우선순위 큐가 비었을 때
if(stack.isEmpty()) { // 스택이 비었을 때 현재 값 결과에 추가
curTime += curPlaytime;
answer[count] = curName;
count++;
}
else { // 스택에 안비었다면 스택 빌때까지 결과에 추가
answer[count] = curName;
count++;
while(!stack.isEmpty()) {
Work rem = stack.pop();
answer[count] = rem.name;
count++;
}
}
}
}
return answer;
}
}