给你一个二进制字符串数组 strs 和两个整数 m 和 n 。
请你找出并返回 strs 的最大子集的长度,该子集中 最多 有 m 个 0 和 n 个 1 。
如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集 。
题解
1.动态规划法
- 动态规划:背包问题
- 若用递归,则递归中的取字符串和不取就对应于背包问题中的拿物品和不拿物品
- 1.dp[i][j][k]:取了前i个字符串后最多取得j个0和k个1的最大的子集的个数 dp=new int[strs.length+1][m+1][n+1](第一个维度+1是为了避免分类讨论(假设第一个字符串为空字符串),后面两个维度+1是因为要取到m和n)
- 2.转移方程:dp[i][j][k]=Math.max(dp[i][j][k],dp[i-1][j-strs[i].zeros][k-strs[j].ones]+1)
- 3.遍历方向 从左至右 从上至下
- 4.返回值 dp[strs.length][m][n]
class Solution {
public int findMaxForm(String[] strs, int m, int n) {
int[][][] dp=new int[strs.length+1][m+1][n+1];
for(int i=1;i<=strs.length;i++){
//j,和k,代表的是背包的容量,如果都从1开始,那么就默认了,当j=0,k=1和j=1,k=0时不能装东西,但是比如“0”或者“1”就能装进去.所以j和k要从0开始
for(int j=0;j<=m;j++){
for(int k=0;k<=n;k++){
//统计strs[i]中1的个数
int ones=0;
//注意有下标偏移 strs[i-1]对应于strs[i]
for(int p=0;p<strs[i-1].length();p++){
if(strs[i-1].charAt(p)=='1') ones++;
}
//strs[i]中0的个数
int zeros=strs[i-1].length()-ones;
dp[i][j][k]=dp[i-1][j][k];//不取strs[i]的情况
//写动态转移方程时一定要考虑边界条件
if(j>=zeros&&k>=ones){
dp[i][j][k]=Math.max(dp[i][j][k],dp[i-1][j-zeros][k-ones]+1);//取strs[i]的情况
}
}
}
}
return dp[strs.length][m][n];
}
}
回溯法(错误)
尝试了回溯法,因为超时只有部分用例通过
//回溯
class Solution {
ArrayList<ArrayList<String>> res = new ArrayList<>();
ArrayList<String> path = new ArrayList<>();
public int findMaxForm(String[] strs, int m, int n) {
dfs(0,0,0,strs,m,n);
int count=0;
for(int i=0;i<res.size();i++){
count=Math.max(count,res.get(i).size());
//System.out.print(res.get(i));
}
return count;
}
//i:当前0的个数 j:当前1的个数
public void dfs(int i, int j,int index,String[] strs, int m, int n){
//终止条件
//注意i,j是上一层0和1的数量,而index是本层的strs编号,所以要分开讨论
if(index>strs.length||i>m||j>n) return;
//加入所有可能的结果
res.add(new ArrayList<>(path));
if(index==strs.length) return;
//当前层操作
//统计strs[index]中1的数目
int count=0;
for(int p=0;p<strs[index].length();p++){
if(strs[index].charAt(p)=='1') count++;
}
//将strs[index]加入path
path.add(strs[index]);
//加入当前strs[index]
dfs(i+strs[index].length()-count,j+count,index+1,strs,m,n);
path.remove(path.size()-1);
//不加当前strs[index]
dfs(i,j,index+1,strs,m,n);
}
}