Paint House II 解答

Question

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?

Solution

这里时间复杂度是O(nk),说明要求我们用O(k)的时间计算每一层的新的cost。

cost'[i] = costs[m][i] + min{cost[0], cost[1], ..., cost[i - 1], cost[i + 1], ..., cost[k - 1]}

原想法是对每一个i重新计算,时间复杂度是O(k2)。包含了大量的重复计算

其实我们只需求出cost[]序列的最小值和第二小的值。Time complexity O(k)

 1 public class Solution {
 2     public int minCostII(int[][] costs) {
 3         if (costs == null || costs.length < 1) {
 4             return 0;
 5         }
 6         int m = costs.length, k = costs[0].length;
 7         int[] cost = new int[k];
 8         int[] tmp = new int[k];
 9         for (int i = 0; i < k; i++) {
10             cost[i] = costs[m - 1][i];
11         }
12         for (int i = m - 2; i >= 0; i--) {
13             // calculate most and second minimum number
14             int[] min = calcMin(cost);
15             for (int j = 0; j < k; j++) {
16                 // if cost[j] is minimum, then add second minimum with costs[i][j]
17                 if (cost[j] == min[0]) {
18                     cost[j] = min[1] + costs[i][j];
19                 } else {
20                     // if cost[j] is not minimum, then add minimum with costs[i][j]
21                     cost[j] = min[0] + costs[i][j];
22                 }
23             }
24         }
25         if (k < 2) {
26             return cost[0];
27         }
28         int[] result = calcMin(cost);
29         return result[0];
30     }
31     
32     private int[] calcMin(int[] nums) {
33         if (nums == null || nums.length < 2) {
34             return new int[0];
35         }
36         int[] mins = new int[2];
37         mins[0] = Math.min(nums[0], nums[1]);
38         mins[1] = Math.max(nums[0], nums[1]);
39         for (int i = 2; i < nums.length; i++) {
40             if (nums[i] < mins[0]) {
41                 mins[1] = mins[0];
42                 mins[0] = nums[i];
43             } else if (nums[i] < mins[1]) {
44                 mins[1] = nums[i];
45             }
46         }
47         return mins;
48     }
49 }
原文地址:https://www.cnblogs.com/ireneyanglan/p/4948901.html