474.一和零
给你一个二进制字符串数组 strs 和两个整数 m 和 n 。
请你找出并返回 strs 的最大子集的长度,该子集中 最多 有 m 个 0 和 n 个 1 。
如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集 。
示例 1:
输入:strs = [“10”, “0001”, “111001”, “1”, “0”], m = 5, n = 3
输出:4
解释:最多有 5 个 0 和 3 个 1 的最大子集是 {“10”,“0001”,“1”,“0”} ,因此答案是 4 。
其他满足题意但较小的子集包括 {“0001”,“1”} 和 {“10”,“1”,“0”} 。{“111001”} 不满足题意,因为它含 4 个 1 ,大于 n 的值 3 。
示例 2:
输入:strs = [“10”, “0”, “1”], m = 1, n = 1
输出:2
解释:最大的子集是 {“0”, “1”} ,所以答案是 2 。
思考
回溯法超时 崩溃!!
package 力扣;
import java.text.BreakIterator;
/**
* @author yyq
* @create 2022-06-19 19:00
*/
public class leetcode474 {
int countZero = 0;
int countOne = 0;
int maxlength=0;
public int findMaxForm(String[] strs, int m, int n) {
int[][] rec=new int[strs.length][2];
for (int i = 0; i < strs.length; i++) {
for (int j = 0; j < strs[i].length(); j++) {
if(strs[i].charAt(j)=='0'){
rec[i][0]++;
}
if(strs[i].charAt(j)=='1') {
rec[i][1]++;
}
}
}
int length = 0;
int startIndex = 0;
backTracking(startIndex,length,rec,m,n);
return maxlength;
}
private void backTracking(int startIndex, int length, int[][] rec, int m, int n) {
if(countZero<=m&&countOne<=n){
if(length>maxlength){
maxlength = length;
}
}
for (int i=startIndex;i<rec.length;i++){
if(countZero+rec[i][0]>m||countOne+rec[i][1]>n){
continue;
}
length++;
countZero = countZero+rec[i][0];
countOne = countOne+rec[i][1];
backTracking(i+1,length,rec,m,n);
length--;
countZero = countZero-rec[i][0];
countOne = countOne-rec[i][1];
}
}
}
实在没办法 还是看题解吧
leetcode题解如下
dp数组的定义及下标的意义
dp[i][j][k] 表示在前0-i个字符串中,使用了j个0和k个1的情况下最多可以得到的字符串数量。
假设str字符串数组长度为l,最终答案就是 dp[l][m][n]
注意:leetcode题解中i=0代表没有字符串,我感觉不太合适,这里i=0对应着str[0]的字符串
数组初始化
假设第i个字符串的 : 字符’0’的个数为 zeroNum , 字符’1’的个数为 oneNum
当i=0时,对于 dp[i=0][j][k]
if zeroNum>j || oneNum>k
dp[i=0][j][k] = 0;
else
dp[i=0][j][k] = 1;
当 j=0与k=0时,dp[i][j][k]=0
状态转移方程
假设第i个字符串的 : 字符’0’的个数为 zeroNum , 字符’1’的个数为 oneNum
当 0 和 1 的容量分别是 j 和 k 时,考虑以下两种情况:
- 如果j<zeroNum || k<oneNum ,不能选第 i 个字符串
- dp[i][j][k] = dp[i-1][j][k]
- 如果j≥zeroNum && k≥oneNum
- 如果不选第i个字符串 ,dp[i][j][k] =dp[i-1][j][k]
- 如果选第i个字符串,dp[i][j][k] =dp[i-1][j-zeroNum][k-oneNum]+ 1
- 故 dp[i][j][k] = MAX{dp[i-1][j][k],dp[i-1][j-zeroNum][k-oneNum]+ 1}
代码省略