0 1 Knapsack Problem in DSA Java - Time & Space Complexity
We want to understand how the time needed to solve the 0 1 Knapsack problem changes as the number of items or the knapsack capacity grows.
How does the algorithm's work increase when we add more items or increase the capacity?
Analyze the time complexity of the following code snippet.
public int knapsack(int[] weights, int[] values, int capacity) {
int n = weights.length;
int[][] dp = new int[n + 1][capacity + 1];
for (int i = 1; i <= n; i++) {
for (int w = 1; w <= capacity; w++) {
if (weights[i - 1] <= w) {
dp[i][w] = Math.max(dp[i - 1][w], dp[i - 1][w - weights[i - 1]] + values[i - 1]);
} else {
dp[i][w] = dp[i - 1][w];
}
}
}
return dp[n][capacity];
}
This code solves the 0 1 Knapsack problem using dynamic programming by filling a table of size items x capacity.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Nested loops over items and capacity filling the dp table.
- How many times: Outer loop runs n times (number of items), inner loop runs capacity times.
As we add more items or increase capacity, the work grows by multiplying these two factors.
| Input Size (n items, capacity W) | Approx. Operations |
|---|---|
| 10 items, capacity 10 | 100 |
| 100 items, capacity 100 | 10,000 |
| 1000 items, capacity 1000 | 1,000,000 |
Pattern observation: The operations grow roughly by multiplying the number of items and capacity, so doubling either doubles the work.
Time Complexity: O(n * W)
This means the time needed grows proportionally to the number of items times the capacity of the knapsack.
[X] Wrong: "The algorithm runs in linear time O(n) because it just loops over items once."
[OK] Correct: The algorithm also loops over all capacities for each item, so the total work depends on both items and capacity, not just items.
Understanding this time complexity helps you explain how dynamic programming improves over naive methods and shows your grasp of how input size affects performance.
"What if we used recursion with memoization instead of a bottom-up table? How would the time complexity change?"
Practice
Solution
Step 1: Understand the problem goal
The 0 1 Knapsack Problem tries to select items to maximize total value without exceeding the weight capacity.Step 2: Identify the constraint
The total weight of selected items must not exceed the knapsack's capacity.Final Answer:
The total value of items without exceeding the weight limit -> Option AQuick Check:
Maximize value under weight limit = The total value of items without exceeding the weight limit [OK]
- Confusing weight maximization with value maximization
- Ignoring the weight limit constraint
- Thinking the problem counts items instead of values
Solution
Step 1: Understand DP array dimensions
We use a 2D array with rows for items (n+1) and columns for weight capacities (W+1).Step 2: Check Java syntax for 2D array
Correct syntax is int[][] dp = new int[n+1][W+1];Final Answer:
int[][] dp = new int[n+1][W+1]; -> Option BQuick Check:
2D array with items and weights = int[][] dp = new int[n+1][W+1]; [OK]
- Using 1D array instead of 2D
- Swapping dimensions incorrectly
- Wrong Java syntax for array declaration
int[] weights = {1, 3, 4};
int[] values = {10, 40, 50};
int capacity = 7;
int n = weights.length;
int[][] dp = new int[n+1][capacity+1];
for (int i = 1; i <= n; i++) {
for (int w = 1; w <= capacity; w++) {
if (weights[i-1] <= w) {
dp[i][w] = Math.max(values[i-1] + dp[i-1][w - weights[i-1]], dp[i-1][w]);
} else {
dp[i][w] = dp[i-1][w];
}
}
}
System.out.println(dp[n][capacity]);Solution
Step 1: Fill DP table for each item and capacity
Key values: - Item 1 (w=1, v=10): dp[1][1..7] = 10 - Item 2 (w=3, v=40): dp[2][1..2]=10, dp[2][3]=40, dp[2][4..7]=50 - Item 3 (w=4, v=50): dp[3][1..2]=10, dp[3][3]=40, dp[3][4]=50, dp[3][5..6]=60, dp[3][7]=90 (max(50 + dp[2][3]=90, 50))Step 2: Find maximum value at dp[n][capacity]
dp[3][7] = 90 (select items 2 and 3: 40 + 50 = 90, weights 3+4=7)Final Answer:
90 -> Option CQuick Check:
Max value for capacity 7 = 90 [OK]
- Adding values without checking weight limit
- Confusing indices in arrays
- Forgetting to consider previous dp values
int[] weights = {2, 3, 4};
int[] values = {3, 4, 5};
int capacity = 5;
int n = weights.length;
int[][] dp = new int[n][capacity+1];
for (int i = 1; i <= n; i++) {
for (int w = 1; w <= capacity; w++) {
if (weights[i-1] <= w) {
dp[i][w] = Math.max(values[i-1] + dp[i-1][w - weights[i-1]], dp[i-1][w]);
} else {
dp[i][w] = dp[i-1][w];
}
}
}Solution
Step 1: Check dp array size and indexing
dp is declared as int[n][capacity+1], but loops use i from 1 to n, accessing dp[i], which causes ArrayIndexOutOfBoundsException.Step 2: Fix dp size to match loop indices
Declare dp as int[n+1][capacity+1] to allow indexing from 0 to n safely.Final Answer:
Change dp array size to int[n+1][capacity+1] -> Option AQuick Check:
Array size must match loop indices [OK]
- Using dp size smaller than loop range
- Starting loop from 0 but indexing from 1
- Ignoring array index exceptions
Solution
Step 1: Calculate maximum value using DP
Check combinations: - Items 3 and 7 weights sum to 10, values 5 + 4 = 9 (3 weight item value is 5, 7 weight item value is 4) - Items 2,3,5 weights sum to 10, values 1+5+2=8 - Items 3 and 7 give 9 value, better than others - Items 2 and 7 sum weight 9, values 1+4=5 Maximum value is 9 with items 3 and 7.Step 2: Verify selected items
Selected items are weights 3 and 7 with values 5 and 4 respectively.Final Answer:
Maximum value 9; items with weights 3 and 7 selected -> Option DQuick Check:
Max value 9 with weights 3+7 = 10 capacity [OK]
- Adding values without checking total weight
- Selecting items exceeding capacity
- Confusing item weights and values
Ready to prove it?
Pass the test and this pattern moves unknown
