0 - 1 Knapsack Problem
0 - 1 Knapsack Problem is a medium dynamic programming problem solved with the knapsack pattern.
The best approach, optimal (1d array, capacity descending), runs in O(n · W) time and O(W) space.
Below are 3 approaches in Java, from recursion (pick / not pick) up.
Problem
Given n items with values val[i] and weights wt[i], and a bag of capacity W, choose a subset of items (each used at most once, no fractions) with total weight at most W and the maximum total value.
Examples
Example 1
- Input
W = 4, val = [1, 2, 3], wt = [4, 5, 1]- Output
3- Why
- Items 0 (weight 4) and 2 (weight 1) cannot both fit; item 2 alone is worth 3.
Example 2
- Input
W = 7, val = [10, 40, 30, 50], wt = [5, 4, 6, 3]- Output
90- Why
- Items 1 and 3: weight 7, value 90.
Constraints
1 <= n <= 1000,1 <= W <= 1000.- Each item is taken whole, at most once.
Animated walkthrough
A narrated, step-by-step animation that builds the solution from the idea up. Press play, or step through it at your own pace.
Concepts first, then the problem and every approach, step by step.
Space to play or pause · ← → to jump a step · click or drag the bar to seek
Solutions
Try it yourself first. Then compare: each approach lists its idea, the steps, its time and space, and the Java code.
| Approach | Time | Space |
|---|---|---|
| Recursion (pick / not pick) | O(2ⁿ) | O(n) |
| 2D tabulation | O(n · W) | O(n · W) |
| Optimal (1D array, capacity descending) | O(n · W) | O(W) |
1Recursion (pick / not pick)
O(2ⁿ)O(n)For each item, either take it (if it fits) or leave it, and take the better result.
- f(i, w) = max(f(i - 1, w), val[i] + f(i - 1, w - wt[i]) if it fits).
class Solution {
static int knapsack(int W, int[] val, int[] wt) {
return f(val, wt, val.length - 1, W);
}
private static int f(int[] val, int[] wt, int i, int w) {
if (i < 0) return 0;
int skip = f(val, wt, i - 1, w);
if (wt[i] > w) return skip;
return Math.max(skip, val[i] + f(val, wt, i - 1, w - wt[i]));
}
}22D tabulation
O(n · W)O(n · W)dp[i][w] = best value using the first i items with capacity w.
- dp[i][w] = dp[i - 1][w]; if wt fits, max with val + dp[i - 1][w - wt].
class Solution {
static int knapsack(int W, int[] val, int[] wt) {
int n = val.length;
int[][] dp = new int[n + 1][W + 1];
for (int i = 1; i <= n; i++)
for (int w = 0; w <= W; w++) {
dp[i][w] = dp[i - 1][w];
if (wt[i - 1] <= w) dp[i][w] = Math.max(dp[i][w], val[i - 1] + dp[i - 1][w - wt[i - 1]]);
}
return dp[n][W];
}
}3Optimal (1D array, capacity descending)
O(n · W)O(W)Keep one row. Iterating capacity from W down to wt[i] means dp[w - wt] still holds the previous item's value, so each item is counted once.
- For each item, for w from W down to wt: dp[w] = max(dp[w], val + dp[w - wt]).
class Solution {
static int knapsack(int W, int[] val, int[] wt) {
int[] dp = new int[W + 1];
for (int i = 0; i < val.length; i++)
for (int w = W; w >= wt[i]; w--)
dp[w] = Math.max(dp[w], val[i] + dp[w - wt[i]]);
return dp[W];
}
}Edge cases to test
- No item fits
- An item exactly equal to the capacity
Hints
Hint 1
For item i and capacity w: skip it (dp[i - 1][w]) or take it (val[i] + dp[i - 1][w - wt[i]]).
Hint 2
With a 1D array, loop w from high to low so each item is used once.
FAQ
What is the best time complexity for 0 - 1 Knapsack Problem?
Optimal (1D array, capacity descending) runs in O(n · W) time and O(W) extra space.
Which pattern does 0 - 1 Knapsack Problem use?
It is a dynamic programming problem that uses the knapsack pattern. Other problems with the same pattern: Fractional Knapsack, Knapsack with Duplicate Items, Coin Change.
Is there a brute force solution for 0 - 1 Knapsack Problem?
Yes. Recursion (pick / not pick) takes O(2ⁿ) time and O(n) space. For each item, either take it (if it fits) or leave it, and take the better result.
Which edge cases should I test for 0 - 1 Knapsack Problem?
No item fits; An item exactly equal to the capacity.