Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LeetCode] 265. Paint House II #265

Open
grandyang opened this issue May 30, 2019 · 0 comments
Open

[LeetCode] 265. Paint House II #265

grandyang opened this issue May 30, 2019 · 0 comments

Comments

@grandyang
Copy link
Owner

grandyang commented May 30, 2019

 

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.

Example:

Input: [[1,5,3],[2,9,4]]
Output: 5
Explanation: Paint house 0 into color 0, paint house 1 into color 2. Minimum cost: 1 + 4 = 5; 
             Or paint house 0 into color 2, paint house 1 into color 0. Minimum cost: 3 + 2 = 5. 

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

 

这道题是之前那道 Paint House 的拓展,那道题只让用红绿蓝三种颜色来粉刷房子,而这道题让用k种颜色,这道题不能用之前那题的解法,会 TLE。这题的解法的思路还是用 DP,但是在找不同颜色的最小值不是遍历所有不同颜色,而是用 min1 和 min2 来记录之前房子的最小和第二小的花费的颜色,如果当前房子颜色和 min1 相同,那么用 min2 对应的值计算,反之用 min1 对应的值,这种解法实际上也包含了求次小值的方法,感觉也是一种很棒的解题思路,参见代码如下:

 

解法一:

class Solution {
public:
    int minCostII(vector<vector<int>>& costs) {
        if (costs.empty() || costs[0].empty()) return 0;
        vector<vector<int>> dp = costs;
        int min1 = -1, min2 = -1;
        for (int i = 0; i < dp.size(); ++i) {
            int last1 = min1, last2 = min2;
            min1 = -1; min2 = -1;
            for (int j = 0; j < dp[i].size(); ++j) {
                if (j != last1) {
                    dp[i][j] += last1 < 0 ? 0 : dp[i - 1][last1];
                } else {
                    dp[i][j] += last2 < 0 ? 0 : dp[i - 1][last2];
                }
                if (min1 < 0 || dp[i][j] < dp[i][min1]) {
                    min2 = min1; min1 = j;
                } else if (min2 < 0 || dp[i][j] < dp[i][min2]) {
                    min2 = j;
                }
            }
        }
        return dp.back()[min1];
    }
};

 

下面这种解法不需要建立二维 dp 数组,直接用三个变量就可以保存需要的信息即可,参见代码如下:

 

解法二:

class Solution {
public:
    int minCostII(vector<vector<int>>& costs) {
        if (costs.empty() || costs[0].empty()) return 0;
        int min1 = 0, min2 = 0, idx1 = -1;
        for (int i = 0; i < costs.size(); ++i) {
            int m1 = INT_MAX, m2 = m1, id1 = -1;
            for (int j = 0; j < costs[i].size(); ++j) {
                int cost = costs[i][j] + (j == idx1 ? min2 : min1);
                if (cost < m1) {
                    m2 = m1; m1 = cost; id1 = j;
                } else if (cost < m2) {
                    m2 = cost;
                }
            }
            min1 = m1; min2 = m2; idx1 = id1;
        }
        return min1;
    }
};

 

Github 同步地址:

#265

 

类似题目:

Product of Array Except Self

Sliding Window Maximum

Paint House

Paint Fence

 

参考资料:

https://leetcode.com/problems/paint-house-ii/

https://leetcode.com/problems/paint-house-ii/discuss/69509/Easiest-O(1)-space-JAVA-solution

https://leetcode.com/problems/paint-house-ii/discuss/69492/AC-Java-solution-without-extra-space

https://leetcode.com/problems/paint-house-ii/discuss/69495/Fast-DP-Java-solution-Runtime-O(nk)-space-O(1)

 

LeetCode All in One 题目讲解汇总(持续更新中...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant