과제 진행하기

2023.07.11 (TUE)


문제 : 프로그래머스 - LV2. 과제 진행하기


접근법

조건

  1. 과제는 시작하기로 한 시각이 되면 시작
  2. 새로운 과제를 할 시간이면, 기존에 하고 있던 과제를 멈추고 새로운 과제를 시작
    • 만약, 과제를 끝낸 시각에 우선순위는, 새로 시작해야 하는 과제 > 잠시 멈춰둔 과제
  3. 멈춰둔 과제는 가장 최근에 멈춘 과제부터 시작

해결법

  1. plans 배열을 시작 시간을 기준으로 정렬한다.
  2. 스택을 활용하여 잠시 멈춘 과제를 넣는다.
  3. 조건 우선순위에 맞게 코드를 구현한다.

결과 코드

import java.util.*;

class Solution {
    public String[] solution(String[][] plans) {
        String[] answer = new String[plans.length];
        int answer_count = 0;
        Queue<String> q_name = new LinkedList<>();
        Queue<Integer> q_time = new LinkedList<>();
        
        // plans 정렬
        Arrays.sort(plans, new Comparator<String[]>() {
            @Override
            public int compare(String[] arr1, String[] arr2) {
                String[] time1 = arr1[1].split(":");
                String[] time2 = arr2[1].split(":");
                int hourCompare = Integer.parseInt(time1[0]) - Integer.parseInt(time2[0]);
                int minuteCompare = Integer.parseInt(time1[1]) - Integer.parseInt(time2[1]);
                
                return hourCompare != 0 ? hourCompare : minuteCompare;
            }
        });
        
        // 시작 시간 정하기
        int curTime = toMin(plans[0]); // 현재 시각
        String curPlan = plans[0][0]; // 현재 과제명
        int remainTime = Integer.parseInt(plans[0][2]); // 현재 과제 남은 시간
        int count = 1; // 대기 중인 과제 순서
        Stack<String> s_String = new Stack<>(); // 잠시 멈춘 과제명
        Stack<Integer> s_Int = new Stack<>(); // 잠시 멈춘 과제 남은 시간
        
        // 진행
        while (answer_count < plans.length) {
            curTime++;
            remainTime--;
            
            if (remainTime == 0) { // 시간이 다 되면
                answer[answer_count] = curPlan;
                answer_count++;
                curPlan = "";
                
                if (curTime == toMin(plans[count])) { // 다음 과제 시간이라면
                    curPlan = plans[count][0];
                    remainTime = Integer.parseInt(plans[count][2]);
                    count++;
                    if (count == plans.length) {
                        count = 0;
                    }
                }
                else if (!s_String.empty()) { // 잠시 멈춘 과제가 있다면
                    curPlan = s_String.pop();
                    remainTime = s_Int.pop();
                }
            }
            else if (curTime == toMin(plans[count])) { // 다음 과제를 시작해야 한다면
                // 저장
                if (!curPlan.equals("")) {
                    s_String.push(curPlan);
                    s_Int.push(remainTime);
                }
                
                curPlan = plans[count][0];
                remainTime = Integer.parseInt(plans[count][2]);
                count++;
                if (count == plans.length) {
                    count = 0;
                }
            }
        }
        
        return answer;
    }
    
    public static int toMin(String[] strs) {
        String[] time = strs[1].split(":");
        return Integer.parseInt(time[0]) * 60 + Integer.parseInt(time[1]);
    }
}