0/1 Knapsack
Solve this ProblemTest Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
1 ≤ weights.length = values.length ≤ 20 - ◆
1 ≤ weights[i], values[i] ≤ 100 - ◆
0 ≤ capacity ≤ 1000
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
Approach & Solutions
Brute Force — Recursive Without Memoization
BruteEvery item is either left out of the bag or placed into it, and an item can only be placed in if its weight doesn't exceed whatever capacity is still left. Leaving an item out keeps the remaining capacity unchanged for the rest of the items to work with; taking it adds its value to the total and uses up that much capacity for the rest. Since it's never obvious in advance which items are worth taking, both choices are tried at every item that fits, and the larger of the two resulting totals is kept. Running out of items or capacity ends a path with whatever value has been collected so far.
O(2^n)O(n)1class Solution {
2 private int[] weights;
3 private int[] values;
4
5 public int knapsack01(int[] weights, int[] values, int capacity) {
6 this.weights = weights;
7 this.values = values;
8 return solve(0, capacity);
9 }
10
11 private int solve(int i, int capacity) {
12 if (i == weights.length || capacity == 0) return 0;
13 if (weights[i] > capacity) return solve(i + 1, capacity);
14 int skip = solve(i + 1, capacity);
15 int take = values[i] + solve(i + 1, capacity - weights[i]);
16 return Math.max(skip, take);
17 }
18}Optimal — Bottom-Up 1D DP
OptimalTrack, for every capacity from 0 up to the bag's full capacity, the best total value achievable using the items considered so far. Every item can either be skipped (the best value at that capacity stays whatever it already was) or taken (its own value plus the best value achievable at the capacity left over after paying its weight) — whichever is larger becomes the new best at that capacity. Sweeping each item's inner update from the full capacity down to that item's own weight guarantees every item is only ever counted once. After every item has been swept through, the entry at the full capacity holds the answer.
O(n × capacity)O(capacity)1class Solution {
2 public int knapsack01(int[] weights, int[] values, int capacity) {
3 int[] dp = new int[capacity + 1];
4 for (int i = 0; i < weights.length; i++) {
5 for (int w = capacity; w >= weights[i]; w--) {
6 dp[w] = Math.max(dp[w], values[i] + dp[w - weights[i]]);
7 }
8 }
9 return dp[capacity];
10 }
11}