프로그래머스 | LV.2 과제 진행하기 - 구현 문풀 (Java)

728x90

⬛ 프로그래머스 | LV.2 과제 진행하기 - 구현 문풀 (Java)

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

 

프로그래머스

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

programmers.co.kr

문제 설명
문제 설명 2


💚문제 접근 방식

고려해야 할 조건이 까다로워서 구현 과정이 어려웠다.

일단 Work 클래스 선언해서 st 시작 시간 기준으로 오름차순 정렬할 생각을 했고 pQ에다가 담아서 활용했고, Stack활용해서 최근 멈춘 과제 담는 용도로 썼다.

중간 중간 구현이 막히니 머리가 복잡해서 다른 분들 코드도 참고했다.

1) 과제 시작 시간 기준으로 오름차순 정렬

2) - 현재 과제 일단 진행 후 다음 과제 시작 시간 넘어갈 경우 현재 과제 remain 갱신 후 Stack에 담기

3) - 현재 과제 일단 진행 한 값이 다음 시작 시간 전이라면 answer에 이름 담고, 종료 상태에서 Stack 안비었다면 cur 과제로 갱신하고 다음 진행

4) 현재 cur과 curTime 을 갱신시키고 다음 반복 시작

→ 다음 반복을 하는 시점에서 curTime은 일단 진행하고, 계속해서 다음 nx 과제의 시작 시간과 비교를 하기 때문에 스택에서 뽑은 값이 다음 시작 과제보다 작으면 (이전 과제)진행하고, 크면 하다가 다시 새 과제로 세팅하기 때문에 문제가 없다.

💚 제출 코드

import java.util.*;
class Work implements Comparable<Work>{
    String name;
    int st, ed, remain;
    Work(String name, int st, int remain){
        this.name = name;
        this.st = st;
        this.remain = remain;
        this.ed = st + remain;
    }
    @Override
    public int compareTo(Work o){
        return this.st - o.st;//시작 시간 빠른 거 우선
    }
}

class Solution {
    static List<Work> list;
    
    //getTime
    public static int getTime(String time){
        int H = Integer.parseInt(time.split(":")[0]);
        int M = Integer.parseInt(time.split(":")[1]);
        return 60 * H + M;
    }
    
    //솔루션 함수 
    public List<String> solution(String[][] plans) {
        List<String> answer = new ArrayList<>();
        
        PriorityQueue<Work> pQ = new PriorityQueue<>();
        
        for(String[] st : plans){
            String name = st[0];
            int start = getTime(st[1]);
            int remain = Integer.parseInt(st[2]);
            pQ.offer(new Work(name, start, remain));
        }
        //잠시 멈춘 애들 담는 용도 
        Stack<Work> stack = new Stack<>();
        Work cur = pQ.poll();
        int curTime = cur.st;
        
        while(!pQ.isEmpty()){
            //일단 현재 시간 세팅 
           curTime += cur.remain;
            
            if(curTime > pQ.peek().st){ //만약 다음nx의 st시간을 넘어간다면 
                cur.remain = curTime - pQ.peek().st;//현재 remain 갱신 후 
                stack.push(cur);//스택 push
            }else{ //다음 st 안넘어갈 경우 
                answer.add(cur.name);//종료 시키고 
                //그럼에도 여전히 비지 않은 애가 있다면 
                if(!stack.isEmpty()){
                    cur = stack.pop();//현재를 cur로 두고 
                    continue;
                }
            }
            //현재 갱신
            cur = pQ.poll();
            curTime = cur.st;
        }
        //탈출 후 남은 이름 담기 
        answer.add(cur.name);
        while(!stack.isEmpty()){
            answer.add(stack.pop().name);
        }
        
        return answer;
    }
}
728x90