原題地址
https://leetcode.com/problems/ones-and-zeroes/description/
題意
給定一個(gè)包含01串的vector,同時(shí)給定可用的0和1的數(shù)目,在可用數(shù)目范圍內(nèi)從vector中挑選01串,求最多能從vector中挑出多少01串。
思路
背包問(wèn)題的變式吧。
遞推方程為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個(gè)串,給定j個(gè)1,k個(gè)0的情況下能拿出的串的數(shù)目。(代碼里i、j、k都是從1開(kāi)始算的)
代碼
1
提交以下代碼得到了runtime error
,看了下失敗的例子,應(yīng)該是01串的數(shù)目太多了,所以dp數(shù)組太大爆掉了
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 ];
}
};
所以優(yōu)化以下空間復(fù)雜度,去掉表示字符串?dāng)?shù)目的那一維
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 ];
}
};