[LeetCode] 474. Ones and Zeroes

题目链接: 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:

  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 = 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] 表示 i0j1 能够组成的字符串的最大数量。对每一个字符串,统计 01 的个数记为 nZeronOne,对 dp 从右下往左上进行更新,即使用 i (= m -> nZero)0j (= n -> nOne)1 能够组成的字符串的最大数量应该为其 当前值 与 已经使用 i - nZero0j - nOne1 组成的字符串最大数量加 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];
    }
};

你可能感兴趣的:(C++,日常小题,LeetCode)