[프로그래머스] Lv.2 과제 진행하기 JAVA 풀이
문제 Lv.2 과제 진행하기
: 해당 시각에 과제 시작
새로운 과제 시작할 시간이 되면 진행중이던 과제 중단하고 새 과제 시작
진행중이던 과제를 끝냈을 때 잠시 멈춘 과제가 있다면 멈춰둔 과제를 이어서 진행
과제를 끝낸 시각에 중단된 과제, 새 과제 둘 다 남아 있다면 새 과제부터 먼저 진행
: 과제 계획 = 2차원 배열 plans
: plans = [name,start,playtime]
: name = 과제 이름 (알파벳 소문자)
start = 과제의 시작 시각 (hh:mm의 형태 "00:00" ~ "23:59")
playtime = 과제 걸리는 시간 (단위는 분)
: 진행중이던 과제가 끝나는 시간 = 새 과제 시작하는 시간 이면 진행중이던 과제는 끝난 것으로 판단
[코드]
import java.util.*;
class Solution {
class Subject implements Comparable<Subject>{
String name;
int start, playtime;
Subject(String name, int start, int playtime){
this.name = name;
this.start = start;
this.playtime = playtime;
}
@Override
public int compareTo(Subject s){
return this.start - s.start;
}
}
public String[] solution(String[][] plans) {
String[] answer = {};
answer = new String[plans.length];
int idx = 0;
PriorityQueue<Subject> q = new PriorityQueue<>((o1, o2)->(o1.start-o2.start));
for(String[] p:plans){
q.add(new Subject(p[0], convertTime(p[1]), Integer.parseInt(p[2])));
}
Subject s = q.poll();
int now = s.start;
Stack<Subject> stack = new Stack<>();
if(!q.isEmpty() && now+s.playtime > q.peek().start){
stack.push(new Subject(s.name, s.start, s.playtime-(q.peek().start-now)));
now = q.peek().start;
s = q.poll();
}
else{
answer[idx++] = s.name;
now += s.playtime;
if(!q.isEmpty() && now==q.peek().start){
s = q.poll();
}
else if(!stack.isEmpty()){
s = stack.pop();
}
else if(!q.isEmpty()){
s = q.poll();
now = s.start;
}
else break;
}
}
return answer;
}
public static int convertTime(String t){
String[] str = t.split(":");
int min = Integer.parseInt(str[0])*60 + Integer.parseInt(str[1]);
return min;
}
}
: class Subject implements Comparable<Subject>{ 클래스 생성
String name; 과제이름
int start, playtime; 과제 시작시각, 걸리는 시간
Subject(String name, int start, int playtime){ subject에 name, start, playtime 넣기
this.name = name;
this.start = start;
this.playtime = playtime;
}
@Override 상속의 관계에 있는 클래스 간에 하위 클래스가 상위 클래스와 '완전 동일한 메소드'를 덮어쓴다
public int compareTo(Subject s){
return this.start - s.start; 시작시간 오름차순 정렬
}
}
: String[] answer = {}; 과제가 끝나면 answer 배열에 담기
answer = new String[plans.length]; answer 설정
int idx = 0; 인덱스 설정
: PriorityQueue<Subject> q = new PriorityQueue<>((o1, o2)->(o1.start-o2.start));
우선순위 큐를 사용해서 start 숫자 기준 오름차순으로 정렬
: for(String[] p:plans){ plans[name, start, playtime]를 p에 넣기
q.add(new Subject(p[0], convertTime(p[1]), Integer.parseInt(p[2]))); 큐에 과제 넣기
}
: Subject s = q.poll(); Subject s = 큐에서 뺀 것
int now = s.start; now는 s 과제 시작시각
: Stack<Subject> stack = new Stack<>(); 진행 중단한 과제들 넣기
if(!q.isEmpty() && now+s.playtime > q.peek().start){
현재 시각+새 과제 소요 시간 > 다음 과제 시작 시간 이라면 과제 중
stack.push(new Subject(s.name, s.start, s.playtime-(q.peek().start-now)));
stack에 멈춘 과제를 넣고 새 과제 시작 (과제를 수행한 시간 빼기)
now = q.peek().start; 현재 시간 갱신
s = q.poll(); 큐에서 빼면 새롭게 과제 시작
}
else{ 과제 끝낸경우
answer[idx++] = s.name; 완료과제 이름 넣어주기
now += s.playtime; 현시각 갱신
if(!q.isEmpty() && now==q.peek().start){ 새 과제 있다면 과제 시작
s = q.poll(); 새 과제이므로 큐에서 빼기
}
else if(!stack.isEmpty()){ 멈춰있던 과제가 있다면 과제 시작 (= 스택 비어있지 않다면)
s = stack.pop(); 중단 과제이므로 스택에서 빼기
}
else if(!q.isEmpty()){ 멈춰둔 과제가 없고 일정 시간 후에 시작해야 할 과제가 있다면
s = q.poll();
now = s.start; 현재 시각 갱신
}
else break;
}
: return answer; 결과 출력
: public static int convertTime(String t){ 시간 모두 다 분으로 만들기
String[] str = t.split(":");
int min = Integer.parseInt(str[0])*60 + Integer.parseInt(str[1]);
return min;
}
* 독학으로 익히는 코딩이라 틀린 것이 있을 수 있습니다. 오류가 있다면 댓글을 통해 알려주세요. 감사합니다. *