leetcode 2209. 用地毯覆盖后的最少白色砖块

487 阅读1分钟

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]
};