Skip to content

Commit 5c7830d

Browse files
committed
Add documentation for LeetCode problem 265: Paint House II
- Created a new Markdown file detailing the problem statement, solution approaches using standard and optimized dynamic programming, along with their algorithms. - Included a comprehensive summary, time and space complexity analysis, example walkthroughs, and edge cases to enhance understanding. - Provided implementation details and related problems for further exploration.
1 parent 99f8ad7 commit 5c7830d

1 file changed

Lines changed: 193 additions & 0 deletions

File tree

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
---
2+
title: "265. Paint House II"
3+
date: "2025-10-08"
4+
tags: ["Dynamic Programming", "Array"]
5+
related: []
6+
slug: "265-paint-house-ii"
7+
category: "leetcode"
8+
leetcode_url: "https://leetcode.com/problems/paint-house-ii/description/?envType=problem-list-v2&envId=xxzz5vc6"
9+
leetcode_difficulty: "Hard"
10+
leetcode_topics: ["Dynamic Programming", "Array"]
11+
---
12+
13+
# 265. Paint House II
14+
15+
## Summary
16+
Given n houses and k colors, find the minimum cost to paint all houses such that no two adjacent houses have the same color, using dynamic programming with O(n*k) time and O(1) space optimization.
17+
18+
## Problem Description
19+
There are a row of `n` houses, each house can be painted with one of `k` colors. The cost of painting each house with a certain color is different. You have to paint all the houses such that no two adjacent houses have the same color.
20+
21+
The cost of painting each house with a certain color is represented by a `n x k` cost matrix. For example, `costs[0][0]` is the cost of painting house `0` with color `0`; `costs[1][2]` is the cost of painting house `1` with color `2`, and so on.
22+
23+
Return the minimum cost to paint all houses.
24+
25+
**Constraints:**
26+
- `1 <= n <= 100`
27+
- `1 <= k <= 20`
28+
- `1 <= costs[i][j] <= 20`
29+
30+
## Solution Approach
31+
This is a classic dynamic programming problem that can be solved with two approaches:
32+
33+
### Approach 1: Standard DP (O(n*k) time, O(n*k) space)
34+
**Key Insight:** Use DP where `dp[i][j]` represents the minimum cost to paint first i houses, with house i-1 painted color j.
35+
36+
**Algorithm:**
37+
1. `dp[i][j] = costs[i][j] + min(dp[i-1][k] for all k != j)`
38+
2. For each house i and color j, find the minimum cost from previous row excluding the same color j
39+
3. Final answer is `min(dp[n-1])`
40+
41+
### Approach 2: Optimized DP (O(n*k) time, O(1) space)
42+
**Key Insight:** Instead of storing entire DP table, track the minimum and second minimum costs from previous row.
43+
44+
**Algorithm:**
45+
1. For each house, calculate new minimum and second minimum costs
46+
2. For each color j, the cost is `costs[i][j] + (min1 if j != prev_min_color else min2)`
47+
3. Update min1, min2, and prev_min_color for next iteration
48+
49+
## Time & Space Complexity
50+
- **Time Complexity:** O(n*k) for both approaches
51+
- **Space Complexity:** O(n*k) for standard DP, O(1) for optimized DP
52+
53+
## Key Insights
54+
- **Color constraint**: Adjacent houses cannot have same color
55+
- **Optimization trick**: Track min1 and min2 from previous row to avoid O(k) search for each color
56+
- **Edge case handling**: When k=1, houses must use different colors but only one available (impossible if n>1)
57+
- **Small constraints**: n<=100, k<=20 makes O(n*k^2) acceptable but we can optimize to O(n*k)
58+
59+
## Examples / snippets
60+
61+
### Solution Code (Optimized DP)
62+
```python
63+
from typing import List
64+
65+
class Solution:
66+
def minCostII(self, costs: List[List[int]]) -> int:
67+
if not costs or not costs[0]:
68+
return 0
69+
70+
n, k = len(costs), len(costs[0])
71+
72+
# Initialize with first house costs
73+
prev_min1 = prev_min2 = float('inf')
74+
prev_min_color = -1
75+
76+
for j in range(k):
77+
if costs[0][j] < prev_min1:
78+
prev_min2 = prev_min1
79+
prev_min1 = costs[0][j]
80+
prev_min_color = j
81+
elif costs[0][j] < prev_min2:
82+
prev_min2 = costs[0][j]
83+
84+
# Process remaining houses
85+
for i in range(1, n):
86+
curr_min1 = curr_min2 = float('inf')
87+
curr_min_color = -1
88+
89+
for j in range(k):
90+
# Choose the minimum cost from previous row
91+
cost = costs[i][j] + (prev_min2 if j == prev_min_color else prev_min1)
92+
93+
if cost < curr_min1:
94+
curr_min2 = curr_min1
95+
curr_min1 = cost
96+
curr_min_color = j
97+
elif cost < curr_min2:
98+
curr_min2 = cost
99+
100+
prev_min1, prev_min2, prev_min_color = curr_min1, curr_min2, curr_min_color
101+
102+
return prev_min1
103+
```
104+
105+
### Solution Code (Standard DP)
106+
```python
107+
from typing import List
108+
109+
class Solution:
110+
def minCostII(self, costs: List[List[int]]) -> int:
111+
if not costs or not costs[0]:
112+
return 0
113+
114+
n, k = len(costs), len(costs[0])
115+
dp = [[float('inf')] * k for _ in range(n)]
116+
117+
# First house - can use any color
118+
for j in range(k):
119+
dp[0][j] = costs[0][j]
120+
121+
# Fill DP table
122+
for i in range(1, n):
123+
for j in range(k):
124+
# Find minimum cost from previous row, excluding same color
125+
min_prev = float('inf')
126+
for prev_j in range(k):
127+
if prev_j != j:
128+
min_prev = min(min_prev, dp[i-1][prev_j])
129+
130+
dp[i][j] = costs[i][j] + min_prev
131+
132+
# Return minimum cost for last house
133+
return min(dp[n-1])
134+
```
135+
136+
### Example Walkthrough
137+
**Example 1:**
138+
```
139+
Input: costs = [[1,5,3],[2,9,4]]
140+
Output: 5
141+
142+
Explanation:
143+
House 0: Paint with color 0 (cost 1), color 1 (cost 5), or color 2 (cost 3)
144+
House 1: Paint with color 0 (cost 2), color 1 (cost 9), or color 2 (cost 4)
145+
146+
DP Table:
147+
House 0: [1, 5, 3]
148+
House 1: [2+min(5,3)=5, 9+min(1,3)=4, 4+min(1,5)=5] = [5, 4, 5]
149+
150+
Minimum cost: 4 (house 0 color 2, house 1 color 1)
151+
152+
Optimized approach:
153+
- After house 0: min1=1 (color 0), min2=3 (color 2)
154+
- For house 1, color 0: 2 + 3 = 5 (since color 0 != prev min color 0, use min2=3)
155+
- For house 1, color 1: 9 + 1 = 10 (use min1=1)
156+
- For house 1, color 2: 4 + 1 = 5 (since color 2 == prev min color 2, use min2=3? Wait no)
157+
158+
Wait, let me recalculate properly:
159+
- After house 0: min1=1 (color 0), min2=3 (color 2), prev_min_color=0
160+
- For house 1, color 0: 2 + min2 = 2 + 3 = 5 (j=0 == prev_min_color=0, so use min2)
161+
- For house 1, color 1: 9 + min1 = 9 + 1 = 10 (j=1 != prev_min_color=0, so use min1)
162+
- For house 1, color 2: 4 + min1 = 4 + 1 = 5 (j=2 != prev_min_color=0, so use min1)
163+
164+
So we get [5, 10, 5], minimum is 5 ✓
165+
```
166+
167+
**Example 2:**
168+
```
169+
Input: costs = [[1,3],[2,4]]
170+
Output: 5
171+
172+
Explanation:
173+
- Paint house 0 with color 1 (cost 3)
174+
- Paint house 1 with color 0 (cost 2)
175+
- Total cost: 3 + 2 = 5
176+
177+
Alternative: house 0 color 0 (1) + house 1 color 1 (4) = 5, same result.
178+
```
179+
180+
## Edge Cases & Validation
181+
- **Single house**: Return minimum cost among all colors for that house
182+
- **Two houses**: Standard DP works fine
183+
- **k = 1**: If n > 1, impossible (return appropriate value based on constraints)
184+
- **All costs same**: Should work correctly with DP
185+
- **Minimum cost is 0**: Edge case where some costs are 0
186+
- **Large n, small k**: Should handle n=100, k=20 efficiently
187+
188+
## Related Problems
189+
- [256. Paint House](https://leetcode.com/problems/paint-house/) - Similar but with only 3 colors (can be O(1) space)
190+
- [1473. Paint House III](https://leetcode.com/problems/paint-house-iii/) - More complex version with street constraints
191+
- [265. Paint House II](https://leetcode.com/problems/paint-house-ii/) - This problem
192+
- [Dynamic Programming Patterns](https://leetcode.com/tag/dynamic-programming/) - General DP practice
193+
```

0 commit comments

Comments
 (0)