Find Score of an Array After Marking All Elements

medium heap priority queue sorting

Problem

Start with score = 0. Repeatedly choose the smallest unmarked value in nums (on a tie, the smallest index), add it to score, then mark that element and its two adjacent elements if they exist. Continue until every element is marked, and return the final score.

Inputnums = [2, 1, 3, 4, 5, 2]
Output7
Pick 1 (mark indices 0,1,2), then 2 at index 5 (mark 4,5), then 4 at index 3. Score = 1 + 2 + 4 = 7.

def findScore(nums):
    n = len(nums)
    marked = [False] * n
    # (value, index) pairs sorted: smallest value first, then smallest index
    order = sorted(range(n), key=lambda i: (nums[i], i))
    score = 0
    for i in order:
        if marked[i]:          # skip already-marked picks
            continue
        score += nums[i]       # take the smallest unmarked value
        marked[i] = True
        if i - 1 >= 0:
            marked[i - 1] = True   # mark left neighbor
        if i + 1 < n:
            marked[i + 1] = True   # mark right neighbor
    return score
function findScore(nums) {
  const n = nums.length;
  const marked = new Array(n).fill(false);
  // indices sorted by (value, then index)
  const order = [...nums.keys()].sort(
    (a, b) => nums[a] - nums[b] || a - b);
  let score = 0;
  for (const i of order) {
    if (marked[i]) continue;        // skip marked picks
    score += nums[i];               // take smallest unmarked value
    marked[i] = true;
    if (i - 1 >= 0) marked[i - 1] = true;  // left neighbor
    if (i + 1 < n) marked[i + 1] = true;   // right neighbor
  }
  return score;
}
long findScore(int[] nums) {
    int n = nums.length;
    boolean[] marked = new boolean[n];
    Integer[] order = new Integer[n];
    for (int i = 0; i < n; i++) order[i] = i;
    // sort by value, then by index on ties
    Arrays.sort(order, (a, b) ->
        nums[a] != nums[b] ? nums[a] - nums[b] : a - b);
    long score = 0;
    for (int i : order) {
        if (marked[i]) continue;        // skip marked picks
        score += nums[i];               // take smallest unmarked value
        marked[i] = true;
        if (i - 1 >= 0) marked[i - 1] = true;  // left neighbor
        if (i + 1 < n) marked[i + 1] = true;   // right neighbor
    }
    return score;
}
long long findScore(vector<int>& nums) {
    int n = nums.size();
    vector<bool> marked(n, false);
    vector<int> order(n);
    iota(order.begin(), order.end(), 0);
    // sort by value, then by index on ties
    sort(order.begin(), order.end(), [&](int a, int b) {
        return nums[a] != nums[b] ? nums[a] < nums[b] : a < b;
    });
    long long score = 0;
    for (int i : order) {
        if (marked[i]) continue;        // skip marked picks
        score += nums[i];               // take smallest unmarked value
        marked[i] = true;
        if (i - 1 >= 0) marked[i - 1] = true;  // left neighbor
        if (i + 1 < n) marked[i + 1] = true;   // right neighbor
    }
    return score;
}
Time: O(n log n) Space: O(n)