본문 바로가기
알고리즘 문제/Java

[프로그래머스/Java] 과제 진행하기

by 현장 2026. 5. 8.

 

-Code

import java.util.*;

class Solution {
    static class Work {
        String name;
        int startTime;
        int remainTime;

        public Work(String[] plan) {
            this.name = plan[0];
            String[] startSplit = plan[1].split(":");
            this.startTime = (Integer.parseInt(startSplit[0]) * 60) + 
                    Integer.parseInt(startSplit[1]);
            this.remainTime = Integer.parseInt(plan[2]);
        }
        // 일한 시간 계산
        public void working(int time) {
            this.remainTime -= time;
        }
    }

    public String[] solution(String[][] plans) {
        Work[] plansConv = new Work[plans.length];
        for (int i = 0; i < plans.length; i++) {
            Work work = new Work(plans[i]);
            plansConv[i] = work;
        }
        // 시작 시간을 기준으로 정렬
        Arrays.sort(plansConv, Comparator.comparingInt(o -> o.startTime));
        // 들어온 순서로 관리하기 위한 덱
        Deque<Work> workDeq = new ArrayDeque<>();
        // 계산
        String[] answer = new String[plans.length];
        int answerIdx = 0;
        for (int i = 0; i < plansConv.length - 1; i++) {
            Work now = plansConv[i];
            Work next = plansConv[i + 1];

            int timeGap = next.startTime - now.startTime;
            // 일을 끝낼수 있는 경우
            if (now.remainTime <= timeGap) {
                // 결과 추가
                answer[answerIdx++] = now.name;
                // 일을 끝내고 남은 시간 계산
                int remainTime = timeGap - now.remainTime;
                // 시간이 남았으면 덱에 있는 일 진행
                while (!workDeq.isEmpty() && remainTime > 0) {
                    Work remainWork = workDeq.pollLast();
                    // 일을 못끝낸 경우 시간 만큼 일하고 저장
                    if (remainWork.remainTime > remainTime) {
                        remainWork.working(remainTime);
                        workDeq.addLast(remainWork);
                        remainTime = 0;
                    } else {
                        // 일을 끝낸 경우
                        answer[answerIdx++] = remainWork.name;
                        remainTime -= remainWork.remainTime;
                    }
                }
            } else {
                // 일을 못끝낸 경우 시간 만큼 일하고 저장
                now.remainTime -= timeGap;
                workDeq.addLast(now);
            }
        }
        // 마지막일 추가
        answer[answerIdx++] = plansConv[plansConv.length - 1].name;
        // 남은 일 처리
        while (!workDeq.isEmpty()) {
            answer[answerIdx++] = workDeq.pollLast().name;
        }
        return answer;
    }
}

처음에 정렬 후 구하는 것까지 생각하고 구현을 하다가 남은 시간이 있는 경우 계산에서 문제가 생겼습니다.

조금 더 짧게 하기 위해서 남은 시간을 계산하는 과정을 1줄로 풀려고 하면서 여러 문제가 발생해 각각 처리를 다르게 해 주어 해결했습니다. 

추가적으로 for문으로 작성을 했지만 Deque을 2개 이용해서 하면 좀더 짧아질 거 같은 느낌도 들어서 비교하지 못해 조금 아쉬웠습니다.