https://school.programmers.co.kr/learn/courses/15008/lessons/121686
프로세싱 유형이다.
- 첫번째 while문은 인덱스를 기준으로 완료 파악( 좋은 풀이를 먼저 얘기하자면 완료한 프로세스의 수를 기준으로 해야한다.)
대기 큐에 쌓여있고, 현재 시각이 모든 프로세스가 다 불려진 시간이라면 첫번째 while 문에서 빠져나가기때문에 프로세스 호출이 끝나고(인덱스) 대기 큐에 남은 프로세스가 없어야 한다 라고 조건을 세웠는데 이 보다는 완료한 프로세스 수를 기준으로 하는게 간명하고 예외도 없다. - Collections.sort 와 Arrays.sort 의 정렬 기준 람다함수를 Arrays.sort는 매개변수 한개, Collections.sort는 매개변수 두개로 할 수 있다고 오해하고있었다.
자세히는 적지 않으나 함수 정의 타고타고들어가보니까 Collections.sort도 결국은 내부적으로 Object배열로 변환한 뒤 (ex : Integer[]) Arrays.sort 메서드를 활용하여 정렬한다. 어쨌든 둘다 Comparator 및 Comparator 매개변수 활용은 가능하다.
3.대기 큐(PriorityQueue)에 남은 프로세스가 없다면, 반복문을 종료할 것이 아니라 index는 끝까지 갔는지 확인해야한다. 그러면 index가 아직 programs.length-1 보다 작으면…?
예를 들면, 어떤 상황이냐면 현재 시각은 196초이고, 대기중인 프로세스가 없으며, 다음 프로세스의 시작 시간이 196초 이후인 경우이다. 아무 프로세스 진행 시간에 대한 집계 없이 다음 프로세스의 시작 시간으로 현재 시각을 맞춰줘야 다시 제대로 돌아가게 된다.
import java.util.*;
class Program implements Comparable<Program>{
int priority;
int calledTime;
int operationTime;
Program(int[] info){
this.priority = info[0];
this.calledTime = info[1];
this.operationTime = info[2];
}
@Override
public int compareTo(Program other){
if(this.priority == other.priority)
return this.calledTime - other.calledTime;
return this.priority - other.priority;
}
}
class Solution {
public long[] solution(int[][] program) {
long[] answer = new long[11];
int m = program.length;
Arrays.sort(program, (i1, i2) -> {
if(i1[1] == i2[1])
return i1[0] - i2[0];
return i1[1]-i2[1];
});
ArrayList<Program> sortedProgram = new ArrayList<>();
for(int i = 0 ; i < m; i++)
sortedProgram.add(new Program(program[i]));
int currentTime = sortedProgram.get(0).calledTime;
int index = 0;
int count = 0;
PriorityQueue<Program> pq = new PriorityQueue<>();
while(count < sortedProgram.size()){
// 완료한 프로그램의 개수가 전체보다 적을 때 까지
while(index < sortedProgram.size() && sortedProgram.get(index).calledTime <= currentTime){
//아직 검사할 프로세스가 남아있고, 프로세스를 처리할 조건을 만족하는 경우
pq.add(sortedProgram.get(index)); // 큐에 ADD
index ++;
}
if(pq.isEmpty()){
// 만약 큐가 비어있으면, 현재 프로세스 전체가 완료되진 않았는데, 실행가능 조건을
//만족한 프로세스가 없으므로, 조건을변경한다(이 문제에서는 시간을 다음 프로세스의 시작 시간으로 SHIFT).
currentTime = sortedProgram.get(index).calledTime;
}
else{
// 큐가 비어있지 않으면 큐에 있는 프로세스부터 처리
Program now = pq.poll();
answer[now.priority] += currentTime - now.calledTime;
currentTime += now.operationTime;
count++;
}
}
answer[0] =(long)currentTime;
return answer;
}
}
외워둘 만한 코드 구조 요약
pq or q 정의
while(모든 프로세스 처리할때 까지){
while(정렬된 프로세스를 탐색하며 현재 조건을 만족할때 까지 q.add)
if(q가 비여있다면 프로세스를 다 탐색하진 않았지만 q가 비어있다면, 현재 조건이 lock 걸림, 조건을 변경)
else{프로세스 실행 처리}
}