{x}
blog image

Most Beautiful Item for Each Query

You are given a 2D integer array items where items[i] = [pricei, beautyi] denotes the price and beauty of an item respectively.

You are also given a 0-indexed integer array queries. For each queries[j], you want to determine the maximum beauty of an item whose price is less than or equal to queries[j]. If no such item exists, then the answer to this query is 0.

Return an array answer of the same length as queries where answer[j] is the answer to the jth query.

 

Example 1:

Input: items = [[1,2],[3,2],[2,4],[5,6],[3,5]], queries = [1,2,3,4,5,6]
Output: [2,4,5,5,6,6]
Explanation:
- For queries[0]=1, [1,2] is the only item which has price <= 1. Hence, the answer for this query is 2.
- For queries[1]=2, the items which can be considered are [1,2] and [2,4]. 
  The maximum beauty among them is 4.
- For queries[2]=3 and queries[3]=4, the items which can be considered are [1,2], [3,2], [2,4], and [3,5].
  The maximum beauty among them is 5.
- For queries[4]=5 and queries[5]=6, all items can be considered.
  Hence, the answer for them is the maximum beauty of all items, i.e., 6.

Example 2:

Input: items = [[1,2],[1,2],[1,3],[1,4]], queries = [1]
Output: [4]
Explanation: 
The price of every item is equal to 1, so we choose the item with the maximum beauty 4. 
Note that multiple items can have the same price and/or beauty.  

Example 3:

Input: items = [[10,1000]], queries = [5]
Output: [0]
Explanation:
No item has a price less than or equal to 5, so no item can be chosen.
Hence, the answer to the query is 0.

 

Constraints:

  • 1 <= items.length, queries.length <= 105
  • items[i].length == 2
  • 1 <= pricei, beautyi, queries[j] <= 109

Solution Explanation for LeetCode 2070: Most Beautiful Item for Each Query

This problem asks to find the maximum beauty of an item whose price is less than or equal to each query price. We can efficiently solve this using two main approaches: Sorting + Offline Queries and Sorting + Binary Search.

Approach 1: Sorting + Offline Queries

This approach leverages the power of sorting to optimize the search process.

Algorithm:

  1. Sort: Sort the items array by price in ascending order. This allows us to iterate through items in increasing price order. Also, sort the queries by price to process them efficiently.

  2. Iterate and Update: Iterate through the sorted queries. For each query q, maintain a pointer i to iterate through the sorted items. As long as the price of the current item (items[i][0]) is less than or equal to q, update the maximum beauty seen so far (mx) and increment i. The mx value after this inner loop represents the maximum beauty for the current query q.

  3. Store Results: Store the mx value for each query in the ans array.

Time Complexity: O(n log n + m log m), where n is the length of items and m is the length of queries. This is dominated by the sorting operations.

Space Complexity: O(m), where m is the length of queries, to store the results.

This approach utilizes binary search to efficiently find the maximum beauty for each query.

Algorithm:

  1. Sort: Sort the items array by price.

  2. Preprocessing: Iterate through the sorted items. For each item, update its beauty to be the maximum beauty seen so far (including the current item's beauty). This preprocessing step creates a cumulative maximum beauty for each price point.

  3. Binary Search: For each query q, perform a binary search on the sorted items to find the largest index j such that items[j][0] <= q. The beauty of this item (items[j][1]) is the maximum beauty for the query q. Handle the case where no item satisfies the condition (result is 0).

Time Complexity: O((n + m) log n). Sorting takes O(n log n). The preprocessing step takes O(n). The binary search for each query takes O(log n), resulting in O(m log n) for all queries.

Space Complexity: O(n) to store the sorted items (and possibly an additional array for prices if not modifying the original items array in place).

Code Examples (Python)

Approach 1:

def maximumBeauty(items: List[List[int]], queries: List[int]) -> List[int]:
    items.sort()
    n, m = len(items), len(queries)
    ans = [0] * len(queries)
    i = mx = 0
    for q, j in sorted(zip(queries, range(m))):
        while i < n and items[i][0] <= q:
            mx = max(mx, items[i][1])
            i += 1
        ans[j] = mx
    return ans

Approach 2:

import bisect
 
def maximumBeauty(items: List[List[int]], queries: List[int]) -> List[int]:
    items.sort()
    prices = [p for p, _ in items]
    n = len(items)
    mx = [items[0][1]]
    for i in range(1, n):
        mx.append(max(mx[i - 1], items[i][1]))
    ans = []
    for q in queries:
        j = bisect_right(prices, q) - 1
        ans.append(0 if j < 0 else mx[j])
    return ans
 

The choice between these approaches depends on the specific input sizes and performance requirements. For very large input, Approach 1 might be slightly faster because it avoids the overhead of binary search on every query. However, Approach 2's clear separation of sorting, preprocessing, and searching often makes it easier to understand and maintain. Both approaches provide significant performance improvements over naive brute-force solutions.