474. 一和零¶
给你一个二进制字符串数组 strs
和两个整数 m
和 n
。
请你找出并返回 strs
的最大子集的长度,该子集中 最多 有 m
个 0
和 n
个 1
。
如果 x
的所有元素也是 y
的元素,集合 x
是集合 y
的 子集 。
示例 1:
Text Only | |
---|---|
示例 2:
提示:
1 <= strs.length <= 600
1 <= strs[i].length <= 100
strs[i]
仅由'0'
和'1'
组成1 <= m, n <= 100
个人题解¶
建议先完成 416. 分割等和子集 后再完成本题。
二维 dp
滚动数组¶
根据题目,本题需要满足两个条件,0
的数量最多为 m
,1
的数量最多为 n
,那么转换为 01 背包就应该有两个装满条件,一个是装满 0
,一个是装满 1
,显然一维的 dp
数组无法解决这样的问题。
由此引出二维 dp
滚动数组,根据递推公式逐次覆盖上一层 dp
数组实现降低物品项这一维度,从而减少空间复杂度。如果不使用滚动数组降维,那么就应该是三维数组,其中物品项作为一维,0
和 1
的数量作为二维 weight
。
类比一维 dp
滚动数组,可以发现 for
循环变成了三层,因为本题不仅要枚举物品项,还需要枚举 0
和 1
的数量,相当于一维 dp
滚动数组中内层 for
循环枚举了两个 weight
。
动态规划(滚动数组)¶
dp[i][j]
表示由最多i
个0
,j
个1
组成的最大子集中有dp[i][j]
个元素;- 递推公式
dp[i][j] = max(dp[i][j], dp[i - zero][j - one] + 1)
,其中zero
和one
分别为当前枚举项中0
和1
的数量; - 初始化
dp
数组为0
即可; - 遍历顺序参照 416. 分割等和子集 中对一维滚动
dp
数组的说明; - 手动推导
dp
数组无误。