left, right 두 개의 우선순위 큐를 사용하면서 두개의 포인터를 사용할 수 있겠다.
left는 costs의 왼쪽부터, right는 costs의 오른쪽부터 채워 넣는다.
단, 겹치지 않아야 하므로 offer 조건은 항상 leftPointer <= rightPointer
가 함께 붙어야 한다.
따라서 큐 사이즈가 candidates
보다 작고 leftPointer <= rightPointer
이면 해당 큐에 offer한다.
이후에는 둘 중 작은 값이 들어있는 큐에서 원소를 제거하고 총액에 더해주는 식으로 하면 된다.
둘 중 작은 값이 들어있는 큐에서 한 번만 제거하므로 k는 순회마다 1씩 감소하며, k > 0
인 동안에만 수행하면 되겠다.
class Solution {
public long totalCost(int[] costs, int k, int candidates) {
PriorityQueue<Integer> left = new PriorityQueue<>();
PriorityQueue<Integer> right = new PriorityQueue<>();
int leftPointer = 0;
int rightPointer = costs.length - 1;
long cost = 0;
while (k > 0) {
while (left.size() < candidates && leftPointer <= rightPointer) {
left.offer(costs[leftPointer++]);
}
while (right.size() < candidates && leftPointer <= rightPointer) {
right.offer(costs[rightPointer--]);
}
if (!left.isEmpty() && !right.isEmpty()) {
if (left.peek() <= right.peek()) {
cost += left.poll();
} else {
cost += right.poll();
}
} else if (!left.isEmpty()) {
cost += left.poll();
} else {
cost += right.poll();
}
k--;
}
return cost;
}
}