描述
给你一个二进制字符串数组 strs 和两个整数 m 和 n 。
请你找出并返回 strs 的最大子集的大小,该子集中 最多 有 m 个 0 和 n 个 1 。
如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集 。
分析
难点是如何看出是01背包。
把总共的0和1的个数视为背包的容量,每一个字符串视为装进背包的物品。
dp[i][j]表示一个字符串在最多有m个0和n个1的情况下,子集最多有多少个。
把总共的0和1的个数视为背包的容量,也就是背包是一个二维的,不再是一维的。
状态转移方程:一种情况是加入了当前字符串,一种是不加入当前字符串。
初始化:为了避免分类讨论,通常多设置一行。这里可以认为,第 00 个字符串是空串。第 00 行默认初始化为 0。
https://leetcode-cn.com/problems/ones-and-zeroes/solution/dong-tai-gui-hua-zhuan-huan-wei-0-1-bei-bao-wen-ti/
https://leetcode-cn.com/problems/ones-and-zeroes/solution/474-yi-he-ling-01bei-bao-xiang-jie-by-ca-s9vr/
class Solution {
public int findMaxForm(String[] strs, int m, int n) {
if(strs.length == 0 || m == 0 || n ==0){
return 0;
}
int[][] dp = new int[m+1][n+1];
for(String str : strs){
int zeroNum = 0;
int oneNum = 0;
for(int k = 0; k < str.length(); k++){
if(str.charAt(k) == '0'){
zeroNum++;
}else{
oneNum++;
}
}
for(int i = m; i >= zeroNum; i--){
for(int j = n; j >= oneNum; j--){
dp[i][j] = Math.max(dp[i][j],dp[i-zeroNum][j-oneNum]+1);
}
}
}
return dp[m][n];
}
}