265. 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.java

The cost of painting each house with a certain color is represented by a n x k cost matrix. For example, costs0 is the cost of painting house 0 with color 0; costs1 is the cost of painting house 1 with color 2, and so on... Find the minimum cost to paint all houses.code

Note:
All costs are positive integers.leetcode

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

解答:
利用paint house的思路,只不過把三種顏色換成了k種顏色,因此:io

//State: f[i][j] is the minimum cost of painting i houses with color j
    //Function: f[i][j] = Math.min(f[i - 1][k(except j)]) + costs[i][j];
    //Initialize: f[0][j] = costs[0][j];
    //Result: Math.min(f[costs.length - 1][j]);
    public int minCostII(int[][] costs) {
        if (costs == null || costs.length == 0 || costs[0].length == 0) {
            return 0;
        }
        int house = costs.length, color = costs[0].length;
        int[][] f = new int[house][color];
        for (int i = 0; i < color; i++) {
            f[0][i] = costs[0][i];
        }
        
        for (int i = 1; i < house; i++) {
            for (int j = 0; j < color; j++) {
                f[i][j] = Integer.MAX_VALUE;
                for (int k = 0; k < color; k++) {
                    if (k == j) continue;
                    f[i][j] = Math.min(f[i][j], f[i - 1][k] + costs[i][j]);
                }
            }
        }
        
        int result = Integer.MAX_VALUE;
        for (int i = 0; i < color; i++) {
            result = Math.min(result, f[house - 1][i]);
        }
        
        return result;

followup是如何把它的複雜度降到o(nk), 那麼就是若是將顏色的部分只掃一遍。參考leetcode的discuss裏most voted answer, 只須要記錄下每一個house的最小的兩個顏色。若是下一個顏色跟這個顏色不同,就取最小的這個顏色加上此次所選的顏色,並找出最小值;若是下一個顏色跟這個顏色同樣,那麼咱們不能夠取最小的這個顏色,因此咱們取第二小的顏色加上此次所選的顏色。最後把最小的顏色輸出就能夠了。ast

//Only the first two minimum costs count, so we keep track on min1 and min2 for each house
    public int minCostII(int[][] costs) {
        if (costs == null || costs.length == 0 || costs[0].length == 0) {
            return 0;
        }
        
        int house = costs.length, color = costs[0].length;
        
        int min1 = -1, min2 = -1;
        for (int i = 0; i < house; i++) {
            int last1 = min1, last2 = min2;
            min1 = -1; min2 = -1;
            
            for (int j = 0; j < color; j++) {
                if (j != last1) {
                    costs[i][j] += last1 < 0 ? 0 : costs[i - 1][last1];
                } else {
                    costs[i][j] += last2 < 0 ? 0 : costs[i - 1][last2];
                }
                
                if (min1 < 0 || costs[i][j] < costs[i][min1]) {
                    min2 = min1;
                    min1 = j;
                } else if (min2 < 0 || costs[i][j] < costs[i][min2]) {
                    min2 = j;
                }
            }
        }
        
        return costs[house - 1][min1];
    }
相關文章
相關標籤/搜索