-
[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. 구현 로직
- 과제를 시간 순서대로 정렬
- for문을 이용해서 과제 하나씩 탐색
- stack이 비어있을 경우, 과제 하나 삽입
- stack 비어있지 않을 경우, 새로 시작하는 과제와 stack에 있는 과제와의 시간 차를 계산
- 시간 차 > 0 일때까지 반복 작업
- 시간 차보다 stack에 있는 playtime이 더 클 경우, stack에 있는 playtime = playtime - 시간차
- 시간 차보다 stack에 있는 playtime이 작거나 같을 경우, stack의 맨 위 과제를 제거하고 playtime만큼을 제거하고도 새로운 과제를 시작하기 전까지 시간차가 남아있을 수도 있으므로 비교 값을 stack의 맨 위 과제로 갱신
- stack의 맨위부터 하나씩 과제를 처리
3. 유의할 점
- 5.2 부분에서 stack 맨 위 과제를 갱신할 때, stack이 비어있는지 검사를 하지 않아서 런타임 에러가 계속 발생했다. stack empty 체크하는 것을 주의해야겠다.
'Algorithm > Programmers' 카테고리의 다른 글
[Programmers] 리코쳇 로봇 / ⭕ (0) 2024.07.09 [Programmers] 광물 캐기 / ⭕ (0) 2024.07.08 [Programmers] 연속된 부분 수열의 합 / ⭕ (0) 2024.07.04 [Programmers] 두 원 사이의 정수 쌍 / ⭕ (0) 2024.07.02 [Programmers] [PCCP 기출문제] 2번 / 석유 시추 / ⭕ (0) 2024.07.01