Optimal Product Selection — Problem Statement & Solution Guide

ArraysMediumGeneral
TimeO(n)
|
SpaceO(1)

Quick Answer & Algorithm Key Takeaway

Arrays

TopicArrays
PatternGeneral
TimeO(n)
SpaceO(1)

Problem Description

Given an array of products where each product is represented as a two‑element array [rating, price], and an integer budget, design a function that returns a product whose price does not exceed the budget and whose rating is maximal among all affordable products. If several products share the same highest rating within the budget, any one of them may be returned. The function should run efficiently for large inputs.

DSA Pattern Breakdown

DSA Pattern Breakdown

"Optimal Product Selection"

medium

WHY DOES IT MATTER?

This pattern exemplifies the "single‑pass maximum under constraint" paradigm, which appears in budgeting, resource allocation, and real‑time decision systems where latency and memory are critical.

OPTIMIZATION CHALLENGE

Recognizing that only the best affordable candidate matters allows us to discard sorting entirely and maintain just two scalar trackers, collapsing the problem to O(n) time and O(1) auxiliary space.

REAL-WORLD CONNECTION

Think of a cloud‑cost optimizer that must pick the most performant VM instance that fits within a customer's spend limit—scanning the catalog once yields the optimal choice without costly sorting or external services.

In an interview, initialize bestRating to -Infinity and bestProduct to null, then iterate; this pattern is easy to code, avoids off‑by‑one errors, and demonstrates clear, intentional state management.

COMPLEXITY AT A GLANCE

⏱ Time:O(n)
💾 Space:O(1)

Core Theory — Why This Approach?

The problem is a classic selection under a single constraint: we must choose an element with the maximum secondary attribute (rating) while respecting a primary bound (price ≤ budget). A naïve approach might sort the entire array by rating or price, which incurs O(n log n) time, or even examine every possible subset if the requirement were more complex, leading to exponential blow‑up. However, because each product is independent and we only need the single best affordable item, we can solve it in linear time by a single pass, maintaining the current best candidate. This leverages the optimal substructure property: after processing the first i elements, the best affordable product among them is sufficient to decide the final answer when the (i+1)‑th element is examined. The linear scan thus eliminates unnecessary ordering work and uses constant extra space, which is optimal for this single‑constraint selection problem.

Interview Questions on This Problem

Q1How would you adapt the solution to return all products that share the highest rating within the budget instead of just one?

Perform the same linear scan to find the maximal rating among affordable items, then make a second pass (or collect during the first pass) to gather every product whose price ≤ budget and rating equals that maximal rating, yielding O(n) time and O(k) extra space where k is the number of top products.

Q2If the budget constraint changes dynamically (multiple queries with different budgets), what data structure can answer each query in sub‑linear time?

Sort the products by price and build a prefix‑maximum array of ratings; then for each budget perform a binary search to locate the last affordable index and retrieve the stored maximum rating in O(log n) time per query, with O(n) preprocessing.

Q3Explain how you would handle the case where products can have duplicate ratings but you must return the cheapest among the highest‑rated affordable items.

During the linear scan keep two variables: bestRating and bestPrice. When encountering a product with price ≤ budget, update if rating > bestRating, or if rating == bestRating and price < bestPrice. This ensures the cheapest product among the top‑rated ones is selected, still in O(n) time and O(1) space.

Examples

Example 1

Input

products = [[5,120],[8,200],[7,150],[9,300]], budget = 180

Output

[7,150]

Explanation: Only products with price ≤180 are considered: [5,120] and [7,150]. Their ratings are 5 and 7 respectively, so the product with rating 7 is chosen.

Example 2

Input

products = [[4,50],[6,80],[6,70],[3,40]], budget = 75

Output

[6,70]

Explanation: Affordable products are [4,50], [6,70] and [3,40]. The highest rating among them is 6, appearing in two products. Either [6,70] or [6,80] would be valid; the example returns [6,70].

Example 3

Input

products = [[10,500],[9,400],[8,300]], budget = 250

Output

[]

Explanation: No product costs 250 or less, therefore the function returns an empty array to indicate that no suitable product exists.

Constraints

  • 1 <= products.length <= 10^5
  • 0 <= rating <= 10^9
  • 0 <= price <= 10^9
  • 0 <= budget <= 10^9

Optimal Approach & Strategy

Iterate once, updating the best affordable product on the fly, achieving O(n) time and O(1) space.

Brute Force Approach

Sort the array by rating (or price) and then scan to find the first affordable product, which costs O(n log n) time.

Code Solutions

JavaScript Solution
Time: O(n)
function optimalProductSelection(products, budget) {
    let bestRating = -Infinity;
    let bestPrice = -1;
    for(const [rating, price] of products){
        if(price<=budget && rating>bestRating){
            bestRating = rating;
            bestPrice = price;
        }
    }
    if(bestRating===-Infinity) return [];
    return [bestRating, bestPrice];
}

// Driver (same as template)
const readline = require('readline');
const rl = readline.createInterface({input: process.stdin, output: process.stdout});
let lines = [];
rl.on('line', (line) => { lines.push(line.trim()); });
rl.on('close', () => {
    let idx = 0;
    const n = parseInt(lines[idx++]);
    const products = [];
    for(let i=0;i<n;i++){
        const [rating, price] = lines[idx++].split(/\s+/).map(Number);
        products.push([rating, price]);
    }
    const budget = parseInt(lines[idx++]);
    const ans = optimalProductSelection(products, budget);
    if(ans.length===0) console.log('[]');
    else console.log(`[${ans[0]},${ans[1]}]`);
});

Asked in Top Tech Interviews

Infosys

Solve in Interative Editor

Ready to test your code? Open our built-in compiler, run custom test suites, and see detailed complexity analysis reports instantly.