Paint House II
Written on October 31, 2015
Tweet
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.
public class Solution {
public int minCostII(int[][] costs) {
if (costs == null || costs.length == 0) return 0;
int row = costs.length, col = costs[0].length;
int[][] dp = new int[row][col];
for (int j = 0; j < col; j++) {
dp[0][j] = costs[0][j];
}
for (int i = 1; i < row; i++) {
for (int j = 0; j < col; j++) {
int min = Integer.MAX_VALUE;
for (int l = 0; l < col; l++) {
if (l != j) {
min = Math.min(min, dp[i - 1][l]);
}
}
dp[i][j] = min + costs[i][j];
}
}
int result = Integer.MAX_VALUE;
for (int j = 0; j < col; j++) {
result = Math.min(result, dp[row - 1][j]);
}
return result;
}
}
public class Solution {
//Explanation: dp[i][j] represents the min paint cost from house 0 to house i when house i use color j; The formula will be dp[i][j] = Math.min(any k!= j| dp[i-1][k]) + costs[i][j]. Take a closer look at the formula, we don't need an array to represent dp[i][j], we only need to know the min cost to the previous house of any color and if the color j is used on previous house to get prev min cost, use the second min cost that are not using color j on the previous house. So I have three variable to record: prevMin, prevMinColor, prevSecondMin. and the above formula will be translated into: dp[currentHouse][currentColor] = (currentColor == prevMinColor? prevSecondMin: prevMin) + costs[currentHouse][currentColor].
public int minCostII(int[][] costs) {
if (costs == null || costs.length == 0) return 0;
int n = costs.length, k = costs[0].length;
if (k == 1) return n == 1 ? costs[0][0] : -1;
int preMin = 0, preSecMin = 0, preInd = -1;
for (int i = 0; i < n; i++) {
int min = Integer.MAX_VALUE, secMin = Integer.MAX_VALUE, index = -1;
for (int j = 0; j < k; j++) {
int cost = costs[i][j] + (j == preInd ? preSecMin : preMin);
//i == 0,初始化cost = cost[i][j],只有第一次才执行
if (index == -1) {
min = cost;
index = j;
} else if (cost < min) {
secMin = min;
min = cost;
index = j;
} else if (cost < secMin) {
secMin = cost;
}
}
preMin = min;
preSecMin = secMin;
preInd = index;
}
return preMin;
}
}