ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Programmers] 과제 진행하기 / ⭕
    Algorithm/Programmers 2024. 7. 5. 22:29
     

    프로그래머스

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

    programmers.co.kr

     

    1. 제출 코드 (2시간 19분 57초 / 구현)

    import java.util.*;
    
    class Solution {
        static class Node {
            String name;
            String start;
            int playtime;
            public Node(String name, String start, int playtime) {
                this.name = name;
                this.start = start;
                this.playtime = playtime;
            }
        }
        public String[] solution(String[][] plans) {
            String[] answer = new String[plans.length];
            int index = 0;
            // 과제 실행 순서
            ArrayDeque<Node> st = new ArrayDeque<>();
            // 과제 시간 순서대로 정렬
            Arrays.sort(plans, (o1, o2) -> {
                String[] t1 = o1[1].split(":");
                String[] t2 = o2[1].split(":");
                int time_diff = Integer.parseInt(t1[0]) - Integer.parseInt(t2[0]);
                if(time_diff != 0) {
                    return time_diff;
                } else {
                    return Integer.parseInt(t1[1]) - Integer.parseInt(t2[1]);
                }
            });
        	
            for(int i = 0; i < plans.length; i++) {
                Node start = new Node(plans[i][0], plans[i][1], Integer.parseInt(plans[i][2]));
                // 과제가 없을 경우
                if(st.isEmpty()) {
                    st.add(start);
                } else {
                    Node t = st.peekLast();
                    int time_diff = calc_time(t, start);
                    // 과제를 새로 시작하기 전까지 끝나는 과제 처리
                    while(time_diff > 0) {
                    	// 만약, 진행 중인 과제가 새로 시작하는 과제 시간 이상으로 해야한다면 playtime 업데이트
                        if(time_diff < t.playtime) {
                            t.playtime = t.playtime - time_diff;
                            break;
                        } else {
                        	// 과제를 새로 시작하기 전에 처리될 수 있는 진행 과제 삭제
                            Node temp = st.pollLast();
                            time_diff -= temp.playtime;
                            answer[index++] = temp.name;
                            if(st.isEmpty()) break;
                            // 진행 중인 과제를 중간에 처리했으니 새로운 과제 부여
                            t = st.peekLast();
                        } 
                    }
                    st.add(start);
                }
            }
            while(!st.isEmpty()) {
                answer[index++] = st.pollLast().name;
            }
            return answer;
        }
        // 새로 시작하는 과제와 잠시 멈춰둔 과제 사이의 시간 측정(분 단위)
        private int calc_time(Node t1, Node t2) {
            String[] ts1 = t1.start.split(":");
            String[] ts2 = t2.start.split(":");
            int m1 = Integer.parseInt(ts1[1]);
            int m2 = Integer.parseInt(ts2[1]);
            int time_diff = 0;
            int diff_hour = Integer.parseInt(ts2[0]) - Integer.parseInt(ts1[0]);
            if(diff_hour > 0) {
                if(m2 < m1) {
                    time_diff += (diff_hour - 1) * 60;    
                } else {
                    time_diff += diff_hour * 60;
                }
            }
            if(m2 >= m1) {
                time_diff += m2 - m1;
            } else {
                time_diff += (60 - m1) + m2;
            }
            return time_diff;
        }
    }

     

    2. 구현 로직

    1. 과제를 시간 순서대로 정렬
    2. for문을 이용해서 과제 하나씩 탐색
    3. stack이 비어있을 경우, 과제 하나 삽입
    4. stack 비어있지 않을 경우, 새로 시작하는 과제와 stack에 있는 과제와의 시간 차를 계산
    5. 시간 차 > 0 일때까지 반복 작업
      1. 시간 차보다 stack에 있는 playtime이 더 클 경우, stack에 있는 playtime  = playtime - 시간차
      2. 시간 차보다 stack에 있는 playtime이 작거나 같을 경우, stack의 맨 위 과제를 제거하고 playtime만큼을 제거하고도 새로운 과제를 시작하기 전까지 시간차가 남아있을 수도 있으므로 비교 값을 stack의 맨 위 과제로 갱신
    6. stack의 맨위부터 하나씩 과제를 처리 

     

    3. 유의할 점

    • 5.2 부분에서 stack 맨 위 과제를 갱신할 때, stack이 비어있는지 검사를 하지 않아서 런타임 에러가 계속 발생했다. stack empty 체크하는 것을 주의해야겠다.
Designed by Tistory.