Fruits Into Baskets III

medium segment tree binary search array

Problem

You have arrays fruits and baskets, each of length n. fruits[i] is the quantity of fruit type i; baskets[j] is the capacity of basket j.

Going left to right, each fruit type must be placed in the leftmost still-empty basket whose capacity is ≥ the fruit's quantity. Each basket holds only one type, and a fruit that fits nowhere stays unplaced. Return how many fruit types remain unplaced.

Inputfruits = [4,2,5], baskets = [3,5,4]
Output1
4 → basket[1]=5, 2 → basket[0]=3, 5 has no basket left (only basket[2]=4 < 5). One unplaced.

def numOfUnplacedFruits(fruits, baskets):
    n = len(baskets)
    size = 1
    while size < n:
        size *= 2
    tree = [0] * (2 * size)        # max-capacity segment tree
    for i in range(n):
        tree[size + i] = baskets[i]
    for i in range(size - 1, 0, -1):
        tree[i] = max(tree[2 * i], tree[2 * i + 1])

    def place(fruit):
        if tree[1] < fruit:        # no basket can hold it
            return False
        node = 1                   # descend to leftmost fitting leaf
        while node < size:
            if tree[2 * node] >= fruit:
                node = 2 * node
            else:
                node = 2 * node + 1
        tree[node] = -1            # consume that basket
        node //= 2
        while node >= 1:           # refresh ancestors
            tree[node] = max(tree[2 * node], tree[2 * node + 1])
            node //= 2
        return True

    unplaced = 0
    for f in fruits:
        if not place(f):
            unplaced += 1
    return unplaced
function numOfUnplacedFruits(fruits, baskets) {
  const n = baskets.length;
  let size = 1;
  while (size < n) size *= 2;
  const tree = new Array(2 * size).fill(0); // max-capacity segment tree
  for (let i = 0; i < n; i++) tree[size + i] = baskets[i];
  for (let i = size - 1; i >= 1; i--)
    tree[i] = Math.max(tree[2 * i], tree[2 * i + 1]);

  function place(fruit) {
    if (tree[1] < fruit) return false;    // no basket fits
    let node = 1;                         // descend to leftmost fit
    while (node < size) {
      if (tree[2 * node] >= fruit) node = 2 * node;
      else node = 2 * node + 1;
    }
    tree[node] = -1;                      // consume that basket
    for (node = node >> 1; node >= 1; node >>= 1)
      tree[node] = Math.max(tree[2 * node], tree[2 * node + 1]);
    return true;
  }

  let unplaced = 0;
  for (const f of fruits)
    if (!place(f)) unplaced++;
  return unplaced;
}
int numOfUnplacedFruits(int[] fruits, int[] baskets) {
    int n = baskets.length, size = 1;
    while (size < n) size *= 2;
    int[] tree = new int[2 * size];          // max-capacity segment tree
    for (int i = 0; i < n; i++) tree[size + i] = baskets[i];
    for (int i = size - 1; i >= 1; i--)
        tree[i] = Math.max(tree[2 * i], tree[2 * i + 1]);

    int unplaced = 0;
    for (int f : fruits) {
        if (tree[1] < f) { unplaced++; continue; } // no basket fits
        int node = 1;                        // descend to leftmost fit
        while (node < size)
            node = tree[2 * node] >= f ? 2 * node : 2 * node + 1;
        tree[node] = -1;                     // consume that basket
        for (node >>= 1; node >= 1; node >>= 1)
            tree[node] = Math.max(tree[2 * node], tree[2 * node + 1]);
    }
    return unplaced;
}
int numOfUnplacedFruits(vector<int>& fruits, vector<int>& baskets) {
    int n = baskets.size(), size = 1;
    while (size < n) size *= 2;
    vector<int> tree(2 * size, 0);            // max-capacity segment tree
    for (int i = 0; i < n; i++) tree[size + i] = baskets[i];
    for (int i = size - 1; i >= 1; i--)
        tree[i] = max(tree[2 * i], tree[2 * i + 1]);

    int unplaced = 0;
    for (int f : fruits) {
        if (tree[1] < f) { unplaced++; continue; } // no basket fits
        int node = 1;                        // descend to leftmost fit
        while (node < size)
            node = tree[2 * node] >= f ? 2 * node : 2 * node + 1;
        tree[node] = -1;                     // consume that basket
        for (node >>= 1; node >= 1; node >>= 1)
            tree[node] = max(tree[2 * node], tree[2 * node + 1]);
    }
    return unplaced;
}
Time: O(n log n) Space: O(n)