编程语言
首页 > 编程语言> > 「图解大厂面试高频算法题」动态规划-粉刷房子I

「图解大厂面试高频算法题」动态规划-粉刷房子I

作者:互联网

「图解大厂面试高频算法题」动态规划-粉刷房子I

原题链接: https://leetcode-cn.com/problems/paint-house/

题目介绍

在这里插入图片描述

题目解答

又又又又是动态规划,动态规划的要点是啥来着?发现子问题、找出状态转换方程、优化数组空间。

首先寻找子问题

在这里插入图片描述
题目的原问题是求解粉刷从第0到第N个房子红/蓝/绿这三种颜色所花费的最低开销,这个问题可以拆成如下N个子问题

确定状态转移方程

子问题已经确定出来了,那么如果我们知道了粉刷从第0到第N-1个房子红/蓝/绿这三种颜色所花费的最低开销,那么我们如何根据这个子问题来算出原问题粉刷从第0到第N个房子红/蓝/绿这三种颜色所花费的最低开销呢?

粉刷匠为了让开销达到最小,自学了编程然后搞了3个数组red、blue和green,red[k]表示粉刷从第0到第k个房子红/蓝/绿这三种颜色所花费的最低开销,其中第k个房子粉刷为红色,blue[k]和green[k]亦然,粉刷匠每到达一个房子的时候,都会去更新red[k]、blue[k]和green[k],当粉刷匠来到了第K个房子的时心里可能这么想:

那么我们得出了状态转移方程如下

red[k] = min(blue[k-1], green[k-1]) + cost[k]
blue[k] = min(red[k-1], green[k-1]) + cost[k]
green[k] = min(blue[k-1], red[k-1]) + cost[k]

有了状态转移方程, 那就很容易写出代码了

代码实现(一维动态规划)

class Solution {
    public int minCost(int[][] costs) {
        int[][] dp = new int[costs.length][3];
        // 0 - 红色
        // 1 - 蓝色
        // 2 - 绿色
        dp[0][0] = costs[0][0];
        dp[0][1] = costs[0][1];
        dp[0][2] = costs[0][2];
        for (int i = 1; i < costs.length; i++) {
            dp[i][0] = Math.min(dp[i-1][1], dp[i-1][2]) + costs[i][0];
            dp[i][1] = Math.min(dp[i-1][0], dp[i-1][2]) + costs[i][1];
            dp[i][2] = Math.min(dp[i-1][0], dp[i-1][1]) + costs[i][2];
        }
        return Math.min(dp[costs.length-1][0], Math.min(dp[costs.length-1][1], dp[costs.length-1][2]));
    }
}

复杂度分析

优化空间

上面的一维动态规划解法使用了一个dp数组,我们仔细观察可以发现,计算dp[i]的状态只取决于dp[i-1]的状态,所以我们可以用三个临时变量red/blue/green来代替dp[i-1][0]/dp[i-1][1]/dp[i-1][2]中的值。

class Solution {
    public int minCost(int[][] costs) {
        int[][] dp = new int[costs.length][3];
        int redCost = costs[0][0], blueCost = costs[0][1], greenCost = costs[0][2];
        for (int i = 1; i < costs.length; i++) {
            int newRedCost = Math.min(blueCost, greenCost) + costs[i][0];
            int newBlueCost = Math.min(redCost, greenCost) + costs[i][1];
            int newGreenCost = Math.min(redCost, blueCost) + costs[i][2];
            redCost = newRedCost;
            blueCost = newBlueCost;
            greenCost = newGreenCost;
        }
        return Math.min(redCost, Math.min(blueCost, greenCost));
    }
}

复杂度分析

标签:开销,int,粉刷,房子,costs,大厂,图解,dp
来源: https://blog.csdn.net/Flames_and_Lights/article/details/121940715