본문 바로가기
Programmers/Lv.2

[프로그래머스] Lv.2 과제 진행하기 JAVA 풀이

by Poorm 푸름 2023. 10. 2.
 

문제 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;
    }
  

 

 

 

* 독학으로 익히는 코딩이라 틀린 것이 있을 수 있습니다. 오류가 있다면 댓글을 통해 알려주세요. 감사합니다. *