Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
2209. 用地毯覆盖后的最少白色砖块
给你一个下标从 0 开始的 二进制 字符串 floor ,它表示地板上砖块的颜色。
floor[i] = '0' 表示地板上第 i 块砖块的颜色是 黑色 。
floor[i] = '1' 表示地板上第 i 块砖块的颜色是 白色 。
同时给你 numCarpets 和 carpetLen 。你有 numCarpets 条 黑色 的地毯,每一条 黑色 的地毯长度都为 carpetLen 块砖块。请你使用这些地毯去覆盖砖块,使得未被覆盖的剩余 白色 砖块的数目 最小 。地毯相互之间可以覆盖。
请你返回没被覆盖的白色砖块的 最少 数目。
示例 1:
输入:floor = "10110101", numCarpets = 2, carpetLen = 2
输出:2
解释:
上图展示了剩余 2 块白色砖块的方案。
没有其他方案可以使未被覆盖的白色砖块少于 2 块。
示例 2:
输入:floor = "11111", numCarpets = 2, carpetLen = 3
输出:0
解释:
上图展示了所有白色砖块都被覆盖的一种方案。
注意,地毯相互之间可以覆盖。
提示:
1 <= carpetLen <= floor.length <= 1000
floor[i] 要么是 '0' ,要么是 '1' 。
1 <= numCarpets <= 1000
题目分析
根据题目所述会给我们一个二进制字符串floor代表现在地毯情况。我们需要将numCarpets条长度为carpetLen的黑色地毯覆盖到现在地毯上。我们可以通过动态规划来解决次问题,定义dp[i][j]代表第i块砖块放j个地毯所剩于最少白色砖块个数。由于下标是从0开始的我们可以将floor长度+1,地毯个数numCarpets+1。这样我们就能更好的访问第第i块砖块放j个地毯所剩于最少白色砖块个数。
分步实现
定义len变量存放二进制字符串floor的长度并初始化dp数组。
let len = floor.length
let dp = new Array(len+1).fill(0).map(item=>{
return new Array(numCarpets+1).fill(0)
})
根据二进制字符串floor初始化对一个的白色砖块数量
for(let i=1; i<len+1; i++){
dp[i][0] = dp[i-1][0]+(Number(floor[i-1]))
}
根据地毯长度carpetLen与地毯个数numCarpets找出对应覆盖后的最少白色砖块个数。
for(let i=carpetLen+1; i<len+1; i++){
for(let j=1; j<numCarpets+1; j++){
dp[i][j] = Math.min(dp[i-carpetLen][j-1], dp[i-1][j]+(Number(floor[i-1])))
}
}
代码实现
/**
* @param {string} floor
* @param {number} numCarpets
* @param {number} carpetLen
* @return {number}
*/
var minimumWhiteTiles = function(floor, numCarpets, carpetLen) {
let len = floor.length
let dp = new Array(len+1).fill(0).map(item=>{
return new Array(numCarpets+1).fill(0)
})
for(let i=1; i<len+1; i++){
dp[i][0] = dp[i-1][0]+(Number(floor[i-1]))
}
for(let i=carpetLen+1; i<len+1; i++){
for(let j=1; j<numCarpets+1; j++){
dp[i][j] = Math.min(dp[i-carpetLen][j-1], dp[i-1][j]+(Number(floor[i-1])))
}
}
return dp[len][numCarpets]
};