[Leetcode] 474. Ones and Zeroes 解题报告

来源:互联网 发布:微商作图软件 编辑:程序博客网 时间:2024/06/07 21:22

题目

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:

  1. The given numbers of 0s and 1s will both not exceed 100
  2. The size of given string array won't exceed 600.

Example 1:

Input: Array = {"10", "0001", "111001", "1", "0"}, m = 5, n = 3Output: 4Explanation: 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 = 1Output: 2Explanation: You could form "10", but then you'd have nothing left. Better form "0" and "1".

思路

又是动态规划的一个变种。我们定义dp[i][j]表示从第0个字符串到截止当前字符串,用i个0和j个1可以构成的字符串的最大数目。那么状态转移方程是:dp[i][j] = max(dp[i - zero_num][j - one_num]),其中zero_num和one_num分别是当前字符串中0和1的数目,i <= zero_num <= m, j <= one_num <= n。需要注意的是:我们必须从后往前更新,这是因为如果从前往后更新,那么如果更新了dp[i][j],就意味着当前dp[i][j]的数量已经包含了s,那么在计算dp[i + ...][j + ...]的时候,用到的dp[i][j]是已经被更新过的(也就是包含了s的数量),所以就会导致重复计算。

算法的时间复杂度是O(l * m * n),其中l是字符串的数量。算法的空间复杂度是O(m*n)。

代码

class Solution {public:    int findMaxForm(vector<string>& strs, int m, int n) {        vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));        for (auto &s : strs) {            int numZeroes = 0, numOnes = 0;            for (auto c : s) {                if (c == '0')                    numZeroes++;                else if (c == '1')                    numOnes++;            }            for (int i = m; i >= numZeroes; i--) {                for (int j = n; j >= numOnes; j--) {                    dp[i][j] = max(dp[i][j], dp[i - numZeroes][j - numOnes] + 1);                }            }        }        return dp[m][n];    }};

原创粉丝点击