原题地址
https://leetcode.com/problems/ones-and-zeroes/description/
题意
给定一个包含01串的vector,同时给定可用的0和1的数目,在可用数目范围内从vector中挑选01串,求最多能从vector中挑出多少01串。
思路
背包问题的变式吧。
递推方程为dp[i][j][k] = max(dp[ i-1 ][ j ][ k ], dp[ i-1 ][ j-count1(str[i]) ][ k-count0(str[i]) ])
dp[i][j][k]表示:前i个串,给定j个1,k个0的情况下能拿出的串的数目。(代码里i、j、k都是从1开始算的)
代码
1
提交以下代码得到了runtime error
,看了下失败的例子,应该是01串的数目太多了,所以dp数组太大爆掉了
class Solution {
public:
int count0(string s) {
int count = 0;
for (int i = 0; i < s.size(); i++) {
if (s[i] == '0') count++;
}
return count;
}
int count1(string s) {
int count = 0;
for (int i = 0; i < s.size(); i++) {
if (s[i] == '1') count++;
}
return count;
}
int findMaxForm(vector<string>& strs, int m, int n) {
int s = strs.size();
int dp[s + 1][m + 1][n + 1];
for (int j = 0; j <= m; j++) {
for (int k = 0; k <= n; k++) {
dp[0][j][k] = 0;
}
}
for (int i = 1; i <= s; i++) {
for (int j = 0; j <= m; j++) {
for (int k = 0; k <= n; k++) {
int temp = 0;
if (j >= count0(strs[i-1]) && k >= count1(strs[i-1]) ) {
temp = dp[i - 1][j - count0(strs[i-1])][k - count1(strs[i-1])] + 1;
}
dp[i][j][k] = max(dp[i - 1][j][k], temp);
}
}
}
return dp[s ][m ][n ];
}
};
所以优化以下空间复杂度,去掉表示字符串数目的那一维
2
class Solution {
public:
int count0(string s) {
int count = 0;
for (int i = 0; i < s.size(); i++) {
if (s[i] == '0') count++;
}
return count;
}
int count1(string s) {
int count = 0;
for (int i = 0; i < s.size(); i++) {
if (s[i] == '1') count++;
}
return count;
}
int findMaxForm(vector<string>& strs, int m, int n) {
int s = strs.size();
int dp[m + 1][n + 1];
for (int j = 0; j <= m; j++) {
for (int k = 0; k <= n; k++) {
dp[j][k] = 0;
}
}
for (int i = 1; i <= s; i++) {
for (int j = m; j >= 0; j--) {
for (int k = n; k >= 0; k--) {
int temp = 0;
if (j >= count0(strs[i - 1]) && k >= count1(strs[i - 1]) ) {
temp = dp[j - count0(strs[i - 1])][k - count1(strs[i - 1])] + 1;
}
dp[j][k] = max(dp[j][k], temp);
}
}
}
return dp[m ][n ];
}
};