BackhardGreedy

Optimized Subset Selection Solution

Problem Statement

Given a set of items, each with a value and a size, determine the optimal subset of these items to include in a collection of limited capacity, allowing for fractional parts of items to be selected, such that the total value of the selected items is maximized.

Example 1
Input
items = [[25, 2.5], [50, 5]], capacity = 10
Output
250.0

Explanation: Step-by-step: We first sort the items by their value-to-size ratio in descending order. Then, we iterate over the sorted items and select each item with a fractional part until the capacity is reached. In this case, we select the first item with a value of 25 and a size of 2.5, resulting in a total value of 250.0.

Example 2
Input
items = [[100, 10], [50, 5]], capacity = 0
Output
0.0

Explanation: Step-by-step: Since the capacity is 0, we cannot select any items. Therefore, the total value is 0.0.

Constraints

  • 1 <= number of items <= 1000
  • 1 <= size and value of each item <= 10000
  • 1 <= capacity <= 10000
  • All sizes and values are integers
Live Compiler1 Free Run Available
Loading Editor...
Test Cases & Output
Click "Run" to test your 1 free compile trial!

🚀 Practice this problem

Run code, get AI hints & track streak

Sign Up Free

Optimized Subset Selection — Problem Statement & Solution Guide

GreedyHardFractional Knapsack
TimeO(n log n)
|
SpaceO(1) additional (in‑place sort) or O(n) if using auxiliary array

Problem Description

Given a set of items, each with a value and a size, determine the optimal subset of these items to include in a collection of limited capacity, allowing for fractional parts of items to be selected, such that the total value of the selected items is maximized.

DSA Pattern Breakdown

DSA Pattern Breakdown

"Optimized Subset Selection"

hard

WHY DOES IT MATTER?

The greedy pattern for fractional knapsack exemplifies how sorting by a locally optimal metric (value‑to‑size ratio) can yield a globally optimal solution in linear‑programming‑compatible problems, a principle that recurs in resource allocation, load balancing, and real‑time scheduling.

OPTIMIZATION CHALLENGE

The key insight is recognizing that the problem's objective is linear, allowing the exchange argument to prove that sorting by ratio reduces the search space from exponential to O(n log n) while preserving optimality.

REAL-WORLD CONNECTION

Think of a cloud provider allocating CPU credits to tenants: each tenant requests a certain amount of compute (size) for a revenue (value). The provider fills its capacity by serving the highest revenue‑per‑CPU tenants first, possibly granting partial credits, mirroring the fractional knapsack greedy selection.

In an interview, compute the ratio on the fly during sorting to avoid extra storage, and use a stable sort if you need to preserve original ordering for tie‑breakers; also, handle edge cases (zero size) before the sort to prevent division errors.

COMPLEXITY AT A GLANCE

⏱ Time:O(n log n)
💾 Space:O(1) additional (in‑place sort) or O(n) if using auxiliary array

Core Theory — Why This Approach?

The Optimized Subset Selection problem is a classic instance of the fractional knapsack problem, where each item i is defined by a value v_i and a size s_i, and the knapsack has a capacity C. Unlike the 0/1 knapsack, we are allowed to take any fraction f (0 ≤ f ≤ 1) of an item, turning the problem into a continuous optimization that can be solved optimally with a greedy strategy. The greedy algorithm sorts items by their value‑to‑size ratio (v_i / s_i) in descending order and then picks items in that order, fully taking each item until the remaining capacity cannot accommodate the whole item, at which point it takes the exact fractional part needed to fill the knapsack. This approach works because the objective function is linear and the feasible region is a convex polytope; the highest marginal gain per unit size must always be chosen first, guaranteeing global optimality.

Naïve solutions—such as enumerating all subsets or using dynamic programming designed for the 0/1 variant—explode combinatorially (O(2^n) subsets) or require O(nC) time and space, which is infeasible when n or C are large (e.g., n > 10^5, C up to 10^9). These methods also ignore the fractional nature of the problem, leading to sub‑optimal results. The optimal greedy paradigm reduces the problem to a single sort (O(n log n)) followed by a linear scan (O(n)), delivering a provably optimal solution with dramatically lower resource consumption.

The theoretical foundation rests on the exchange argument: if an optimal solution ever picks an item with a lower ratio before one with a higher ratio, swapping a small amount of the lower‑ratio item with the higher‑ratio one strictly improves total value, contradicting optimality. Hence, the sorted‑by‑ratio order is the only ordering that can satisfy optimality, making the greedy algorithm both necessary and sufficient for the fractional knapsack.

Interview Questions on This Problem

Q1How would you modify the fractional knapsack solution to handle items with zero size or zero value?

Items with zero size but positive value can be taken entirely without affecting capacity, so they should be added to the total value upfront. Items with zero value contribute nothing, so they can be ignored. The algorithm should filter these cases before sorting to avoid division‑by‑zero when computing ratios.

Q2Explain why the greedy approach fails for the 0/1 knapsack but succeeds for the fractional version.

In the 0/1 knapsack, taking an item entirely may block the inclusion of a combination of smaller items that together yield higher total value, breaking the optimal‑substructure property. The fractional version allows splitting items, preserving linearity of the objective, so the marginal gain per unit size is always the correct local decision, leading to a globally optimal solution.

Q3A company wants to maximize profit from advertising slots where each slot can be partially purchased. How would you model this as a fractional knapsack and what additional constraints might you need to consider?

Model each ad slot as an item with profit = expected revenue and size = duration or audience reach, with the total budget as capacity. Additional constraints could include minimum purchase thresholds, mutually exclusive slots, or time‑window restrictions, which would require augmenting the greedy solution with preprocessing (e.g., filtering) or post‑processing checks.

Examples

Example 1

Input

items = [[25, 2.5], [50, 5]], capacity = 10

Output

250.0

Explanation: Step-by-step: We first sort the items by their value-to-size ratio in descending order. Then, we iterate over the sorted items and select each item with a fractional part until the capacity is reached. In this case, we select the first item with a value of 25 and a size of 2.5, resulting in a total value of 250.0.

Example 2

Input

items = [[100, 10], [50, 5]], capacity = 0

Output

0.0

Explanation: Step-by-step: Since the capacity is 0, we cannot select any items. Therefore, the total value is 0.0.

Constraints

  • 1 <= number of items <= 1000
  • 1 <= size and value of each item <= 10000
  • 1 <= capacity <= 10000
  • All sizes and values are integers

Optimal Approach & Strategy

Sort items by descending value‑to‑size ratio and then linearly scan, taking whole items until capacity runs out, then take the needed fraction of the next item.

Brute Force Approach

Enumerate every possible subset and every possible fraction of each item, computing total value and checking capacity, which is exponential in the number of items.

Verified Code Solutions

JavaScript Solution
Time: O(n log n)
function solution(items, capacity) {
      items.sort((a, b) => b[0] / b[1] - a[0] / a[1]);
      let totalValue = 0;
      for (let i = 0; i < items.length; i++) {
         let fractionalPart = Math.min(1, capacity / items[i][1]);
         totalValue += items[i][0] * fractionalPart;
         capacity -= items[i][1] * fractionalPart;
         if (capacity <= 0) break;
      }
      return totalValue;
   }

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.