持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情
题目详情
LeetCode题库序号 剑指 Offer II 091. 粉刷房子 ,难度为 中等。
Tag : 「动态规划」
假如有一排房子,共 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
动态规划
题解思路:
这道题目是关于动态规划的,我原先还认为是可以使用深度优先搜索,但是不可行的,因为问题之间是存在关联性的,比如我想要知道第i个房子粉刷的费用消耗,我需要加上第i-1个房子粉刷的费用消耗,虽然第0号房的粉刷费用可以非常快的得知,但是这个需要和第1号房做一个搭配组合,作为最小值的比较。由此我们可以推到出公式为:
dp[i][j]=min(dp[i−1][(j+1)mod3],dp[i−1][(j+2)mod3])+costs[i][j]
我们可以根据公式的逻辑来进行编码即可。
题解代码
public class Solution {
public int minCost(int[][] costs) {
int n = costs.length;
int[] dp = new int[3];
for (int j = 0; j < 3; j++) {
dp[j] = costs[0][j];
}
for (int i = 1; i < n; i++) {
int[] dpNew = new int[3];
for (int j = 0; j < 3; j++) {
dpNew[j] = Math.min(dp[(j + 1) % 3], dp[(j + 2) % 3]) + costs[i][j];
}
dp = dpNew;
}
return Arrays.stream(dp).min().getAsInt();
}
}
结尾
我的"刷完LeetCode题库"系列文章的第 剑指 Offer II 091 序号的题目,本次刷题之旅系列开始于 2022-06-12,因为LeetCode上部分是有锁题,我自己的目标是将先把所有不带锁的题目刷完。自己能够通过这次刷题之旅勉励自己,并且提升逻辑思维能力。这个系列的文章就是会见证我自己的一个成长过程!
思路虽然不是最优的,但是我会尽我所能!
为了让我自己的刷题之旅不中断,我特地建立了相关的仓库,来记录我自己的刷题之旅。 github.com/jackpan123/… 。