题目链接: https://leetcode.com/problems/ones-and-zeroes/description/
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:
- The given numbers of
0sand1swill both not exceed100 - The size of given string array won’t exceed
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 两者之间的最大值。至于为什么要从右下往左上更新的原因是,避免重复计算相同字符串,确保使用上一轮保存下来的值来计算新一轮的值。
Code
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];
}
};

本文介绍了一道LeetCode上的经典动态规划问题:如何利用给定数量的0和1形成尽可能多的字符串。通过对每个字符串中0和1的数量统计,采用动态规划的方法,实现了一个高效的解决方案。
107

被折叠的 条评论
为什么被折叠?



