Leetcode: Paint House II

There are a row of n houses, each house can be painted with one of the 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.

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... Find the minimum cost to paint all houses.

Note:
All costs are positive integers.

Follow up:
Could you solve it in O(nk) runtime?

Time Complexity: O(n*k*k)

 1 public class Solution {
 2     public int minCostII(int[][] costs) {
 3         if (costs==null || costs.length==0 || costs[0].length==0) return 0;
 4         int n = costs.length;
 5         int k = costs[0].length;
 6         int[][] dp = new int[n][k];
 7         for (int j=0; j<k; j++) {
 8             dp[0][j] = costs[0][j];
 9         }
10         
11         for (int i=1; i<n; i++) {
12             for (int j=0; j<k; j++) {
13                 int min = Integer.MAX_VALUE;
14                 for (int t=0; t<k; t++) {
15                     min = (t==j)? min : Math.min(min, dp[i-1][t]);
16                 }
17                 dp[i][j] = min + costs[i][j];
18             }
19         }
20         
21         int res = Integer.MAX_VALUE;
22         for (int j=0; j<k; j++) {
23             res = Math.min(res, dp[n-1][j]);
24         }
25         return res;
26     }
27 }

Better Solution: 参考: https://leetcode.com/discuss/54415/ac-java-solution-without-extra-space

Time Complexity: O(N*K), Space Complexity: O(1)

The idea is similar to the problem Paint House I, for each house and each color, the minimum cost of painting the house with that color should be the minimum cost of painting previous houses, and make sure the previous house doesn't paint with the same color.

We can use min1 and min2 to track the indices of the 1st and 2nd smallest cost till previous house, if the current color's index is same as min1, then we have to go with min2, otherwise we can safely go with min1.

The code below modifies the value of costs[][] so we don't need extra space.

min1 min2分别记录1st and 2nd smallest previous cost's last house color

 1 public int minCostII(int[][] costs) {
 2     if (costs == null || costs.length == 0) return 0;
 3 
 4     int n = costs.length, k = costs[0].length;
 5     // min1 is the index of the 1st-smallest cost till previous house
 6     // min2 is the index of the 2nd-smallest cost till previous house
 7     int min1 = -1, min2 = -1;
 8 
 9     for (int i = 0; i < n; i++) {
10         int last1 = min1, last2 = min2;
11         min1 = -1; min2 = -1;
12 
13         for (int j = 0; j < k; j++) {
14             if (j != last1) {
15                 // current color j is different to last min1
16                 costs[i][j] += last1 < 0 ? 0 : costs[i - 1][last1];
17             } else {
18                 costs[i][j] += last2 < 0 ? 0 : costs[i - 1][last2];
19             }
20 
21             // find the indices of 1st and 2nd smallest cost of painting current house i
22             if (min1 < 0 || costs[i][j] < costs[i][min1]) {
23                 min2 = min1; min1 = j;
24             } else if (min2 < 0 || costs[i][j] < costs[i][min2]) {
25                 min2 = j;
26             }
27         }
28     }
29 
30     return costs[n - 1][min1];
31 }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值