携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情
刷题的日常
一天一题,保持脑子清爽
粉刷房子
来自leetcode的 剑指 Offer II 091 题,题意如下:
假如有一排房子,共 n 个,每个房子可以被粉刷成红色、蓝色或者绿色这三种颜色中的一种,你需要粉刷所有的房子并且使其相邻的两个房子颜色不能相同。
当然,因为市场上不同颜色油漆的价格不同,所以房子粉刷成不同颜色的花费成本也是不同的。每个房子粉刷成不同颜色的花费是以一个n x 3的正整数矩阵 costs 来表示的。
例如,costs[0][0] 表示第 0 号房子粉刷成红色的成本花费;costs[1][2]表示第 1 号房子粉刷成绿色的花费,以此类推。
请计算出粉刷完所有房子最少的花费成本。
给出的例子有:
输入: costs = [[17,2,17],[16,16,5],[14,3,19]]
输出: 10
解释: 将 0 号房子粉刷成蓝色,1 号房子粉刷成绿色,2 号房子粉刷成蓝色。
最少花费: 2 + 5 + 3 = 10。
理解题意
题目不难,可以将条件提取出来:
- 题目会给出一个数组
- 给定的数组里面还是个数组,这层数组固定有三个值,代表粉刷不同颜色的费用
- 要找出不同代价最低的粉刷方案
- 注意:相邻的房子颜色不能相同
做题思路
一开始没注意相邻房子的颜色不能相同,直接获取代价最低的数字做了汇总,惨痛。
这一题其实可以用动态规划去做。从最上面出发,每层汇总最低代价,除开颜色相同的,最终把三层中最低的代价返回即可。
代码实现
代码实现也很简单,如下:
public class Solution {
public int minCost(int[][] costs) {
int result = Integer.MAX_VALUE, min;
for (int i : costs[0]) {
result = Math.min(result, i);
}
for (int i = 1; i < costs.length; i++) {
int[] cost = costs[i];
int[] pre = costs[i - 1];
for (int j = 0; j < cost.length; j++) {
min = Integer.MAX_VALUE;
for (int p = 0; p < pre.length; p++) {
if (p == j) {
continue;
}
min = Math.min(min, pre[p]);
}
cost[j] = cost[j] + min;
}
}
result = Integer.MAX_VALUE;
for (int j : costs[costs.length - 1]) {
result = Math.min(result, j);
}
return result;
}
}