|
| 1 | +# Paint House |
| 2 | + |
| 3 | +You are a renowned painter who is given a task to paint n houses in a row. You can paint each house with one of three colors: Red, Blue, or Green. The cost of painting each house with each color is different and given in a 2D array costs: |
| 4 | + |
| 5 | +- costs[i][0] = cost of painting house `i` Red |
| 6 | +- costs[i][1] = cost of painting house `i` Blue |
| 7 | +- costs[i][2] = cost of painting house `i` Green |
| 8 | + |
| 9 | +No two neighboring houses can have the same color. Return the minimum cost to paint all houses. |
| 10 | + |
| 11 | +## Constraints |
| 12 | + |
| 13 | +- 1 ≤ n ≤ 100 |
| 14 | +- costs[i].length == 3 |
| 15 | +- 1 ≤ costs[i][j] ≤ 1000 |
| 16 | + |
| 17 | +## Examples |
| 18 | + |
| 19 | +Example 1 |
| 20 | + |
| 21 | +```text |
| 22 | +costs = [[8, 4, 15], [10, 7, 3], [6, 9, 12]] |
| 23 | +Output: 13 |
| 24 | +
|
| 25 | +Explanation: |
| 26 | +
|
| 27 | +House 0: Blue (cost = 4) |
| 28 | +House 1: Green (cost = 3) |
| 29 | +House 2: Red (cost = 6) |
| 30 | +Total = 4 + 3 + 6 = 13 |
| 31 | +
|
| 32 | +``` |
| 33 | + |
| 34 | +Example 2 |
| 35 | +```text |
| 36 | +Input: |
| 37 | +
|
| 38 | +costs = [[5, 8, 6], [19, 14, 13], [7, 5, 12], [14, 5, 9]] |
| 39 | +Output: 30 |
| 40 | +
|
| 41 | +Explanation: Red(5) → Green(13) → Red(7) → Blue(5) = 30 |
| 42 | +``` |
| 43 | + |
| 44 | +## Solution |
| 45 | + |
| 46 | +The solution implements a space-optimized dynamic programming approach using three variables to track the minimum costs. |
| 47 | + |
| 48 | +Variable Initialization: |
| 49 | + |
| 50 | +prev_min_cost_red = 0: Minimum cost if the current house is painted red (color 0) |
| 51 | +prev_min_cost_blue = 0: Minimum cost if the current house is painted blue (color 1) |
| 52 | +prev_min_cost_green = 0: Minimum cost if the current house is painted green (color 2) |
| 53 | + |
| 54 | +These start at 0 because before painting any house, the cost is 0. |
| 55 | + |
| 56 | +Main Loop: The algorithm iterates through each house's costs using tuple unpacking: |
| 57 | + |
| 58 | +```python |
| 59 | +for cost_red, cost_blue, cost_green in costs: |
| 60 | + # |
| 61 | +``` |
| 62 | + |
| 63 | +Where cost_red, cost_blue, cost_green represent the costs of painting the current house with red, blue, and green |
| 64 | +respectively. |
| 65 | + |
| 66 | +State Transition: For each house, we simultaneously update all three variables: |
| 67 | + |
| 68 | +```python |
| 69 | +prev_min_cost_red, prev_min_cost_blue, prev_min_cost_green = min(prev_min_cost_blue, prev_min_cost_green) + cost_red, |
| 70 | +min(prev_min_cost_red, prev_min_cost_green) + cost_blue, min(prev_min_cost_red, prev_min_cost_blue) + cost_green |
| 71 | +``` |
| 72 | + |
| 73 | +Breaking this down: |
| 74 | + |
| 75 | +- New `prev_min_cost_red` (cost if current house is red): `min(prev_min_cost_blue, prev_min_cost_gree) + cost_red` |
| 76 | + We take the minimum of the previous costs where the house was NOT red (either blue or green) |
| 77 | + Add the cost of painting the current house red |
| 78 | + |
| 79 | +- New `prev_min_cost_blue` (cost if current house is blue): `min(prev_min_cost_red, prev_min_cost_green) + cost_blue` |
| 80 | + We take the minimum of the previous costs where the house was NOT blue (either red or green) |
| 81 | + Add the cost of painting the current house blue |
| 82 | + |
| 83 | +- New `prev_min_cost_green` (cost if current house is green): `min(prev_min_cost_red, prev_min_cost_blue) + cost_blue` |
| 84 | + We take the minimum of the previous costs where the house was NOT green (either red or blue) |
| 85 | + Add the cost of painting the current house green |
| 86 | + |
| 87 | +The simultaneous assignment is crucial here - all three values are calculated using the old values before any updates occur. |
| 88 | + |
| 89 | +Final Result: After processing all houses, `prev_min_cost_red`, `prev_min_cost_blue`, and `prev_min_cost_green` contain |
| 90 | +the minimum costs to paint all houses with the last house being red, blue, or green respectively. The answer is the |
| 91 | +minimum among these three values: |
| 92 | + |
| 93 | +`return min(prev_mins_cost_red, prev_min_cost_blue, prev_min_cost_green)` |
| 94 | + |
| 95 | +### Complexity Analysis |
| 96 | + |
| 97 | +#### Time Complexity: O(n) |
| 98 | + |
| 99 | +Where n is the number of houses (length of the costs array). The algorithm iterates through the costs array exactly once, |
| 100 | +performing constant-time operations (comparisons and additions) for each house. |
| 101 | + |
| 102 | +#### Space Complexity: O(1) |
| 103 | + |
| 104 | +The algorithm uses only three variables (`prev_min_cost_red`, `prev_min_cost_blue`, `prev_min_cost_green`) to track the |
| 105 | +minimum costs regardless of the input size. The space usage remains constant as it doesn't create any additional data |
| 106 | +structures that scale with the input. The variables are reused and updated in each iteration rather than storing all |
| 107 | +intermediate results. |
0 commit comments