本题源自leetcode 474
-----------------------------------------------------------------------------------
思路:动态规划
1 遍历字符串数组的每一个字符串。统计0 和 1 的个数。然后用一个二维数组res,记录。i 个 0和 j个1能组成的最大字符串数目。
2 动态数组的更新从右下到左上。
代码:
int findMaxForm(vector<string>& strs, int m, int n) {
vector<vector<int>> res(m+1,vector<int>(n+1,0));
for(string &s : strs){
int count1=0;
int count2=0;
for(int i=0;i<s.length();i++){
if(s[i] == '0')
count1++;
else
count2++;
}
/*
if((count1 <=m && count2 < n) ||(count1 < m && count2 <= n))
res++;
*/
for(int i=m;i >= count1;i--){
for(int j=n;j >= count2;j--){
res[i][j]=max(res[i][j],res[i-count1][j-count2]+1);
}
}
}
return res[m][n];
}
思路2:
代码:
struct comp{
bool operator()(string &s1,string& s2){
return s1.length() != s2.length() ? s1.length() < s2.length() : s1 < s2;
}
};
int findMaxForm(vector<string>& strs, int m, int n) {
sort(strs.begin(),strs.end(),comp());
vector<int> numZeros;
for(auto s : strs){
numZeros.push_back(count(s.begin(),s.end(),'0'));
}
int res=0;
dfs(strs, numZeros, m, n, 0, 0, res);
return res;
}
void dfs(vector<string>& strs, vector<int>& numZero, int m, int n, int start, int form, int& res) {
if(res >= form + strs.size() - start) {
return;
}
res = max(res, form);
for(int i = start; i < strs.size(); i++) {
if(i == start || strs[i] != strs[i-1]) {
int zeros = numZero[i];
int ones = strs[i].length() - zeros;
if(m - zeros >= 0 && n - ones >= 0) {
dfs(strs, numZero, m - zeros, n - ones, i + 1, form + 1, res);
}
}
}
}