문제 링크 : https://programmers.co.kr/learn/courses/30/lessons/42627
문제 설명
하드디스크는 한 번에 하나의 작업만 수행할 수 있습니다. 디스크 컨트롤러를 구현하는 방법은 여러 가지가 있습니다. 가장 일반적인 방법은 요청이 들어온 순서대로 처리하는 것입니다. 각 작업에 대해 [작업이 요청되는 시점, 작업의 소요시간]을 담은 2차원 배열 jobs가 매개변수로 주어질 때, 작업의 요청부터 종료까지 걸린 시간의 평균을 가장 줄이는 방법으로 처리하면 평균이 얼마가 되는지 return 하도록 solution 함수를 작성해주세요. (단, 소수점 이하의 수는 버립니다)
제한사항
- jobs의 길이는 1 이상 500 이하입니다.
- jobs의 각 행은 하나의 작업에 대한 [작업이 요청되는 시점, 작업의 소요시간] 입니다.
- 각 작업에 대해 작업이 요청되는 시간은 0 이상 1,000 이하입니다.
- 각 작업에 대해 작업의 소요시간은 1 이상 1,000 이하입니다.
- 하드디스크가 작업을 수행하고 있지 않을 때에는 먼저 요청이 들어온 작업부터 처리합니다.
** 현재시간 값을 무조건 +1씩 더해주면서, 완료된 작업을 list에서 제거했는데,,, 소스가 너무 길어지고 지저분해졌다.
** 수행 list를 따로 두지 않고, 즉시 완료했다고 가정하고 소요시간을 현재시간 값에 더하니 소스가 매우 깔끔해진 것 같다. (시간복잡도도 줄어 들었다고 판단된다.)
풀이 순서
- 입력된 jobs을 아래 정렬조건으로 PriorityQueue를 이용해 정렬(PriorityQueue를 굳이 안써도 될듯,,)
- 정렬 조건 1) workTime(소요시간)이 짧을수록 앞으로
- 정렬 조건 2) start(요청시간)이 짧을 수록 앞으로
- 현재시간(var: time)을 반복적으로 +1씩 더해주면서, 수행할 Job이 있는지 확인(time >= list.get(i).start)
- 수행할 Job은 완탐으로 돌면서 반복시켜주는게 아니라, 즉시 수행했다고 가정하고 현재시간 값에 해당 job의 workTime(소요시간)을 더해준다. 그 즉시, 해당 Job은 List에서 제거해준다.(list 탐색하는 for문에 break가 있어서 문제가 되진 않는다.)
import java.util.ArrayList;
import java.util.List;
import java.util.PriorityQueue;
class Solution {
public int solution(int[][] jobs) {
PriorityQueue<Job> pq = new PriorityQueue<>();
List<Job> list = new ArrayList<>();
//Job 정렬
for (int i = 0; i < jobs.length; i++) {
pq.add(new Job(jobs[i][0], jobs[i][1]));
}
//list에 정렬 조건1), 2)를 바탕으로 정렬된 Job 순차적으로 삽입
for (int i = 0; i < jobs.length; i++) {
list.add(pq.poll());
}
int time = 0;
int sum = 0;
while (list.size()>0) {
for (int i = 0; i < list.size(); i++) {
// workTime(소요시간)이 짧은 순서부터 조회
// workTime(소요시간)이 짧으면서, start(요청시간)이 짧은 순서대로 작업
if (time>=list.get(i).start) {
// 현재시간에 workTime(소요시간)을 더해줌
time+=list.get(i).workTime;
// 요청부터 종료까지 걸린 시간: 현재시간(time) - start(요청시간)
sum+=time-list.get(i).start;
list.remove(i);
break;
}
// 위 조건에 해당되는 작업이 없다면 time+=1
if (i == list.size()-1) time++;
}
}
int answer = (sum/jobs.length);
return answer;
}
static class Job implements Comparable<Job> {
int start;
int workTime;
public Job(int start, int time) {
this.start = start;
this.workTime = time;
}
// 정렬 조건 1) workTime(소요시간)이 짧을수록 앞으로
// 정렬 조건 2) start(요청시간)이 짧을 수록 앞으로
@Override
public int compareTo(Job o) {
if (this.workTime < o.workTime) return -1;
else if (this.workTime == o.workTime) {
if (this.start < o.start) return -1;
else return 1;
} else return 1;
}
}
}
'Algorithm' 카테고리의 다른 글
[boj17136-완전탐색] 색종이 붙이기 (x) (0) | 2020.02.05 |
---|---|
[프로그래머스 - BFS/DFS] 네트워크 (0) | 2020.01.28 |
[프로그래머스 - 정렬] H-Index (0) | 2020.01.27 |
[프로그래머스 - 정렬] 가장 큰수 (0) | 2020.01.27 |
[프로그래머스 - 스택/큐] 다리를지나는트럭 (0) | 2020.01.27 |