题目链接: https://leetcode.com/problems/ones-and-zeroes/description/
In the computer world, use restricted resource you have to generate maximum benefit is what we always want to pursue.
For now, suppose you are a dominator of m 0s
and n 1s
respectively. On the other hand, there is an array with strings consisting of only 0s
and 1s
.
Now your task is to find the maximum number of strings that you can form with given m 0s
and n 1s
. Each 0
and 1
can be used at most once.
Note:
0s
and 1s
will both not exceed 100
600
.Example 1:
Input: Array = {"10", "0001", "111001", "1", "0"}, m = 5, n = 3
Output: 4
Explanation: This are totally 4 strings can be formed by the using of 5 0s and 3 1s, which are “10,”0001”,”1”,”0”
Example 2:
Input: Array = {"10", "0", "1"}, m = 1, n = 1
Output: 2
Explanation: You could form "10", but then you'd have nothing left. Better form "0" and "1".
动态规划,开辟 (m + 1) × (n + 1)
大小数组 dp
,并用 dp[i][j]
表示 i
个 0
和 j
个 1
能够组成的字符串的最大数量。对每一个字符串,统计 0
和 1
的个数记为 nZero
和 nOne
,对 dp
从右下往左上进行更新,即使用 i (= m -> nZero)
个 0
和 j (= n -> nOne)
个 1
能够组成的字符串的最大数量应该为其 当前值 与 已经使用 i - nZero
个 0
和 j - nOne
个 1
组成的字符串最大数量加 1 两者之间的最大值。至于为什么要从右下往左上更新的原因是,避免重复计算相同字符串,确保使用上一轮保存下来的值来计算新一轮的值。
class Solution {
public:
int findMaxForm(vector<string>& strs, int m, int n) {
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
int nOne, nZero;
for (string& s: strs) {
nOne = nZero = 0;
for (char& ch: s) {
if (ch == '0') {
nZero++;
} else {
nOne++;
}
}
for (int i = m; i >= nZero; --i) {
for (int j = n; j >= nOne; --j) {
dp[i][j] = max(dp[i][j], dp[i - nZero][j - nOne] + 1);
}
}
}
return dp[m][n];
}
};