본문 바로가기
알고리즘/문제 풀이 (출처: 프로그래머스)

[JAVA] 과제 진행하기

by 이민우 2024. 2. 23.
728x90
반응형

https://school.programmers.co.kr/learn/courses/30/lessons/176962

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

 

import java.util.*;

class Solution {
    public String[] solution(String[][] plans) {
        String[] answer = new String[plans.length];
        
        // 다루기 편하게 클래스로 변경
        Homework[] homeworks = new Homework[plans.length];
        for(int i=0; i< plans.length; i++) {
            String[] plan = plans[i];
            // 다루기 편하게 시간*60 + 분 으로 변경
            int time = 0;
            time += Integer.parseInt(plan[1].split(":")[0]) * 60;
            time += Integer.parseInt(plan[1].split(":")[1]);
            int need = Integer.parseInt(plan[2]);
            
            homeworks[i] = new Homework(plan[0], time, need);
        }
        
        // 배열이 시간순으로 정렬되지 않았을 수 있으니 정렬
        Arrays.sort(homeworks);
        
        // 멈춘 과제 목록 : 최근에 멈춘 걸 먼저 해야하므로 LIFO인 Stack 사용
        Stack<Homework> keep = new Stack<>();
        
        // 연산 시작
        int cnt = 0;
        int timenow = 0; // 현재시간
        for(int i=0; i<plans.length; i++) {
            if(keep.isEmpty()) {
                // 멈춘 과제가 없으면 수행
                if(i != plans.length-1) {
                    if(homeworks[i].time + homeworks[i].need <= homeworks[i+1].time) {
                        // 다음 숙제 시작시간 전에 끝낼 수 있으면
                        answer[cnt] = homeworks[i].subject;
                        timenow = homeworks[i].time + homeworks[i].need;
                        cnt++;
                    }
                    else {
                        // 다음 숙제 시작시간 전에 끝낼 수 없으면 남은 시간 저장 및 스택에 저장
                        homeworks[i].need =  homeworks[i].need - (homeworks[i+1].time - homeworks[i].time);
                        keep.push(homeworks[i]);
                        timenow = homeworks[i+1].time;
                    }
                }
                else {
                    // 마지막거.
                    answer[cnt] = homeworks[i].subject;
                    cnt++;
                    timenow = homeworks[i].time + homeworks[i].need;
                }
            }
            else {
                // 멈춘 과제가 있다면
                if(timenow < homeworks[i].time) {
                    // 아직 시작할 시간이 안됐다면 안한거 먼저 수행
                    while(true) {
                        if(keep.isEmpty() || timenow == homeworks[i].time) {
                            // 킵해놓은게 없거나 시간이 됐다면 break
                            break;
                        }
                        Homework keepHomework = keep.pop();
                        if(timenow + keepHomework.need <= homeworks[i].time) {
                            // 다음 숙제 전에 다 끝낼 수 있다면 다하기
                            answer[cnt] = keepHomework.subject;
                            timenow = timenow + keepHomework.need;
                            cnt++;
                            System.out.println(((int)timenow/60) + ":" + timenow%60 + " : " + answer[cnt-1] + "is Done.");
                        }
                        else {
                            keepHomework.need = keepHomework.need - (homeworks[i].time - timenow);
                            keep.push(keepHomework);
                            timenow = homeworks[i].time;
                        }
                    }
                }
                
                // 시작할 시간이 됐다면 지금거 수행
                // 그런데 이 부분은 위의 첫 if와 겹치는 코드임. 잘 짜면 합칠 수 있음.
                if(i != plans.length-1) {
                    if(homeworks[i].time + homeworks[i].need <= homeworks[i+1].time) {
                        // 다음 숙제 시작시간 전에 끝낼 수 있으면
                        answer[cnt] = homeworks[i].subject;
                        timenow = homeworks[i].time + homeworks[i].need;
                        cnt++;
                    }
                    else {
                        // 다음 숙제 시작시간 전에 끝낼 수 없으면 남은 시간 저장 및 스택에 저장
                        homeworks[i].need = homeworks[i].need - (homeworks[i+1].time - homeworks[i].time);
                        keep.push(homeworks[i]);
                        timenow = homeworks[i+1].time;
                    }
                }
                else {
                    answer[cnt] = homeworks[i].subject;
                    cnt++;
                }
            }
        }
        
        // 남은 숙제 순차수행
        while(!keep.isEmpty()) {
            answer[cnt] = keep.pop().subject;
            cnt++;
        }
        
        
        return answer;
    }
    
    class Homework implements Comparable<Homework> {
        
        String subject;
        int time;
        int need;
        
        public Homework(String subject, int time, int need) {
            this.subject = subject;
            this.time = time;
            this.need = need;
        }
        
        @Override
        public int compareTo(Homework h) {
            if(this.time < h.time) {
                return -1;
            }
            return 1;
        }
        
    }
}
728x90
반응형