每天两道LeetCodeHard:(37)

126 阅读2分钟

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.

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.

解释:

给了一个矩阵,要求从每一行中选择一个数,相邻两行不能选择相同的,求总和最小。 时间复杂度要求O(nk)

思考:

这个题相当于是之前那个偷或者不偷的升级版,难点就在于,之前那个题只需要考虑偷,这次对于每一个颜色的选择,都要进行比较。 总的状态转移方程是:对于第i个房子刷第j个颜色的最大收益为dp[i-1][j-1]=min(刨去dp[i-2][j-2]之后dp[i-2]的所有值) 所以其实可以对dp的每一行进行排序,然后在计算当前位置时,先比较最小值和当前颜色是否相同,如果相同则取次小值,如果不同则直接相加即可。 在最后一行找最小值即可实现总的最小。时间复杂度是nklogk 进一步优化可以发现,其实只需要记录当前这一行的最小值以及下标和次最小值即可,如果下一行和最小值同下标,则返回次小值;不然返回最小值即可。这样时间复杂度可以压缩为nk

答案:

class Solution:
    def minCostII(self, costs: List[List[int]]) -> int:
        if not costs:
            return 0
        dp = [[0 for i in range(len(costs[0]))] for j in range(len(costs))]
        dp[0] = costs[0]
        for i in range(1, len(costs)):
            for j in range(len(costs[0])):
                dp[i][j] = min(dp[i - 1][:j] + dp[i - 1][j + 1:]) + costs[i][j]
        return min(dp[-1])

答案补充: