Most Beautiful Items for Each Query

medium binary search sorting prefix max

Problem

You are given items where each item is a [price, beauty] pair, and a list of queries. For every query value, return the greatest beauty among all items whose price is at most that query; if no item is affordable, the answer for that query is 0. Sort items by price, build a running prefix-max of beauty, then binary search each query for the last affordable item.

Inputitems = [[1,2],[3,2],[2,4],[5,6],[3,5]], queries = [1,2,3,4,5,6]
Output[2, 4, 5, 5, 6, 6]
Sorted by price: prices [1,2,3,3,5] with prefix-max beauty [2,4,4,5,6]. Query 3 sees items up to price 3 → best beauty 5.

def maximum_beauty(items, queries):
    items.sort(key=lambda it: it[0])
    prices, best = [], []
    cur = 0
    for price, beauty in items:
        cur = max(cur, beauty)
        prices.append(price)
        best.append(cur)
    out = []
    for q in queries:
        lo, hi = 0, len(prices)
        while lo < hi:
            mid = (lo + hi) // 2
            if prices[mid] <= q:
                lo = mid + 1
            else:
                hi = mid
        out.append(best[lo - 1] if lo > 0 else 0)
    return out
function maximumBeauty(items, queries) {
  items.sort((a, b) => a[0] - b[0]);
  const prices = [], best = [];
  let cur = 0;
  for (const [price, beauty] of items) {
    cur = Math.max(cur, beauty);
    prices.push(price);
    best.push(cur);
  }
  return queries.map(q => {
    let lo = 0, hi = prices.length;
    while (lo < hi) {
      const mid = (lo + hi) >> 1;
      if (prices[mid] <= q) lo = mid + 1;
      else hi = mid;
    }
    return lo > 0 ? best[lo - 1] : 0;
  });
}
class Solution {
    public int[] maximumBeauty(int[][] items, int[] queries) {
        Arrays.sort(items, (a, b) -> a[0] - b[0]);
        int n = items.length;
        int[] prices = new int[n], best = new int[n];
        int cur = 0;
        for (int i = 0; i < n; i++) {
            cur = Math.max(cur, items[i][1]);
            prices[i] = items[i][0];
            best[i] = cur;
        }
        int[] out = new int[queries.length];
        for (int i = 0; i < queries.length; i++) {
            int lo = 0, hi = n;
            while (lo < hi) {
                int mid = (lo + hi) >>> 1;
                if (prices[mid] <= queries[i]) lo = mid + 1;
                else hi = mid;
            }
            out[i] = lo > 0 ? best[lo - 1] : 0;
        }
        return out;
    }
}
vector<int> maximumBeauty(vector<vector<int>>& items, vector<int>& queries) {
    sort(items.begin(), items.end());
    int n = items.size();
    vector<int> prices(n), best(n);
    int cur = 0;
    for (int i = 0; i < n; i++) {
        cur = max(cur, items[i][1]);
        prices[i] = items[i][0];
        best[i] = cur;
    }
    vector<int> out(queries.size());
    for (int i = 0; i < (int)queries.size(); i++) {
        int lo = 0, hi = n;
        while (lo < hi) {
            int mid = (lo + hi) / 2;
            if (prices[mid] <= queries[i]) lo = mid + 1;
            else hi = mid;
        }
        out[i] = lo > 0 ? best[lo - 1] : 0;
    }
    return out;
}
Time: O((n + q) log n) Space: O(n)