디스크 컨트롤러

문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/42627

접근 방식

주어진 2차원 배열에는 요청 시작 시점과, 처리 시간이 담겨있다.

시작 시점을 기준으로 처리하는 경우, 최소 소요 시간을 보장하지 않는다.

따라서, 시작 시점 + 처리 시간을 기준으로 정렬해서, 구하고자 했다.

잘못된 접근

import java.util.*;

class Solution {
    public int solution(int[][] jobs) {
        Arrays.sort(jobs, Comparator.comparingInt(a->a[1]));
        int answer = jobs[0][0]+jobs[0][1];
        int beforeSum = jobs[0][0]+jobs[0][1];
        for(int i=1; i<jobs.length; i++){
            answer+= Math.abs(beforeSum-jobs[i][0])+jobs[i][1];
            beforeSum+=jobs[i][1];
        }
        return answer/jobs.length;
    }
}

결과는 10점, 주어진 케이스는 통과했으나 테스트는 대부분 통과하지 못했다.

정렬 기준이 잘못된 것 같다.

30분 정도 생각을 해 봤지만, 별다른 수가 생각이 나지 않아, 답을 보고 이해하기로 했다.

잘 된 접근

크게 두 파트로 접근할 수 있다.

하나는, 이전의 진입 시간보다 작은 진입 시간을 가지는 작업을 모두 할 일에 넣기.

나머지는, 해당 작업을 처리하면서, 걸리는 시간(대기+소요)과 소요시간을 분리하여 관리할 것.
(현재 내 코드에서의 for문 내의 로직과 동일)

예를 들어서, (1, 2) (1, 3) (2, 5) 가 있다고 가정해보자.

이 상황에서, 일단 0에 진입할 수 있는 작업이 있었으면 넣었겠지만, 없기 때문에 소요 시간이 가장 작은 작업을 넣어야 한다,

(1, 2) 이므로, 이전 진입 시간은 1이 된다.

그리고 다시, 첫 번째 파트를 검증한다. 1보다 작거나 같은 진입시간을 가지는 작업을 큐에 넣는다. (1, 2)(1, 3) 이 된다.

이제 큐에서 작업을 꺼내면서, 로직을 처리한다. 총 소요시간 (꺼낸 작업의 소요 시간 + 이전까지의 대기 시간 - 현재 작업의 진입 시간)을 구한다.

이전 작업의 대기시간에 현재 작업의 대기시간을 더하여 데이터를 갱신한다.

로직을 처리하며 데이터를 갱신한 경우 count+1을 한다.

다시 처음부터 로직을 처리하면서, 모든 작업이 완료될 때 까지 반복한다.

최종적으로는, 총 소요시간 / 배열의 길이 = 평균 소요 시간 를 리턴한다.

결과

소스 코드

import java.util.*;

class Solution {
    public int solution(int[][] jobs) {
        Arrays.sort(jobs, (a, b) -> a[0] - b[0]);
        PriorityQueue<int[]> que = new PriorityQueue<>((a, b) -> a[1] - b[1]);
        int answer = 0;
        int cnt=0, end=0, idx=0;
        while(cnt < jobs.length){ // 모든 작업을 완료
            while(idx < jobs.length && jobs[idx][0] <= end){ // 진입 시간이 이전 대기 시간을 벗어나지 않는 경우
                que.offer(jobs[idx++]); // 작업 추가
            }
            if(que.isEmpty()) end = jobs[idx][0]; // 이전 대기 시간 갱신, 첫 작업의 진입시간이 1이 아닌 경우
            else {
                int cur[] = que.poll(); // 현재 처리 작업
                answer+= end - cur[0] + cur[1];
                end += cur[1];
                cnt++; // 작업 횟수 추가
            }
        }

        return answer/jobs.length;
    }
}

알게 된 점

없음.