content: class Solution {
      public long totalCost(int[] costs, int k, int candidates) {
          // The worker with the lowest cost has the highest priority, if two players has the
          // same cost, break the tie by their indices (0 or 1).
          PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> {
              if (a[0] == b[0]) {
                  return a[1] - b[1];
              }
              return a[0] - b[0];});
          
          // Add the first k workers with section id of 0 and 
          // the last k workers with section id of 1 (without duplication) to pq.
          for (int i = 0; i < candidates; i++) {
              pq.offer(new int[] {costs[i], 0});
          }
          for (int i = Math.max(candidates, costs.length - candidates); i < costs.length; i++) {
              pq.offer(new int[] {costs[i], 1});
          }
  
          long answer = 0;
          int nextHead = candidates;
          int nextTail = costs.length - 1 - candidates;
  
          for (int i = 0; i < k; i++) {
              int[] curWorker = pq.poll();
              int curCost = curWorker[0], curSectionId = curWorker[1];
              answer += curCost;
              
              // Only refill pq if there are workers outside.
              if (nextHead <= nextTail) {
                  if (curSectionId == 0) {
                      pq.offer(new int[]{costs[nextHead], 0});
                      nextHead++;
                  } else {
                      pq.offer(new int[]{costs[nextTail], 1});
                      nextTail--;
                  }
              }
          }
  
          return answer;
      }
  }