持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情
一.题目:
剑指 Offer II 091. 粉刷房子 假如有一排房子,共
n个,每个房子可以被粉刷成红色、蓝色或者绿色这三种颜色中的一种,你需要粉刷所有的房子并且使其相邻的两个房子颜色不能相同。
当然,因为市场上不同颜色油漆的价格不同,所以房子粉刷成不同颜色的花费成本也是不同的。每个房子粉刷成不同颜色的花费是以一个 n x 3 **的正整数矩阵 costs 来表示的。
例如,costs[0][0] 表示第 0 号房子粉刷成红色的成本花费;costs[1][2] 表示第 1 号房子粉刷成绿色的花费,以此类推。
请计算出粉刷完所有房子最少的花费成本。
示例 1:
输入: costs = [[17,2,17],[16,16,5],[14,3,19]]
输出: 10
解释: 将 0 号房子粉刷成蓝色,1 号房子粉刷成绿色,2 号房子粉刷成蓝色。
最少花费: 2 + 5 + 3 = 10。
示例 2:
输入: costs = [[7,6,2]]
输出: 2
提示:
costs.length == ncosts[i].length == 31 <= n <= 1001 <= costs[i][j] <= 20
二、思路分析:
先解读这道题,起初读文字还是没明白题目的意思,后面看到示例结合题目才看到题目的目的。题目要求我们能够将给出的n个房子全部粉刷成各个颜色,要求是相邻的房子不能够粉刷成同样的颜色,以及必须花费到最小。所以这道题目应该使用动态规划进行求解,又因为这道题的每次的最小值依靠上一个房子的花费最小值,所以可以动态规划的优化,本体的基本步骤如下:
- 首先创建一个
三维数组,分别存放当前房子的红蓝绿三种颜色的最小花费。 - 随后创建一个循环一直到
n-1的位置,输出dp[n-1]的最小值即为粉刷所有房子花费的最小值。 - 每次循环内容创建一个新的三维数组用来比较上一个房子的粉刷红蓝绿三种情况的花费,比较得到最小值赋值给
dp,如此循环迭代就能够把所有情况囊括进来。
三、代码:
function minCost(costs: number[][]): number {
const n= costs.length;
let dp: number[] = new Array(3).fill(0);
for(let i=0 ; i<3 ; i++){
dp[i] = costs[0][i];
}
for(let i=1 ; i<n ; i++){
const newDp: number[] = new Array(3).fill(0);
for(let j=0 ; j<3 ; j++){
newDp[j] = Math.min(dp[(j+1)%3], dp[(j+2)%3]) + costs[i][j];
}
dp = newDp;
}
return Math.min(...dp)
};
四、总结:
总体来说这道题目所用到的知识就是
动态规划,但是需要你结合例子仔细地读题目的要求才能够发现如何做这道题目。