###### tags: `Leetcode` `medium` `dynamic programming` `python` `c++` # 474. Ones and Zeroes ## [題目連結:] https://leetcode.com/problems/ones-and-zeroes/ ## 題目: You are given an array of binary strings ```strs``` and two integers ```m``` and ```n```. Return the size of the largest subset of ```strs``` such that there are **at most** ```m``` ```0```'s and ```n``` ```1```'s in the subset. A set ```x``` is a **subset** of a set ```y``` if all elements of ```x``` are also elements of ```y```. **Example 1:** ``` Input: strs = ["10","0001","111001","1","0"], m = 5, n = 3 Output: 4 Explanation: The largest subset with at most 5 0's and 3 1's is {"10", "0001", "1", "0"}, so the answer is 4. Other valid but smaller subsets include {"0001", "1"} and {"10", "1", "0"}. {"111001"} is an invalid subset because it contains 4 1's, greater than the maximum of 3. ``` **Example 2:** ``` Input: strs = ["10","0","1"], m = 1, n = 1 Output: 2 Explanation: The largest subset is {"0", "1"}, so the answer is 2. ``` ## 解題想法: * 此題為數組中每個字符串皆有一些0與1,若給m個0、n個1 * 從數組中取最多的字符串 * 使其字符串中0與1的出現次數不超過m與n * 求次數而非具體細節: 使用DP * 定義dp[i][j]: **表示具有i個0、j個1的最大子集合數** * 對於strs中每個string,先求出該string的0、1數量 * zero * one * 比較對象為: dp[i-zero][j-one]表示當前的i扣掉zero數量、當前的j扣掉one數量,所具有的最大子集合數 * 轉移方程式即為: dp[i][j]=max(dp[i][j], **dp[i-zero][j-one]+1**) * +1表示加入當前string * 注意~填入dp時候,需由大到小進行 * for i in range(m,zero-1,-1): **不能低於zero的數量** * for j in range(n,one-1,-1): **不能低於one的數量** ## Python: ``` python= class Solution(object): def findMaxForm(self, strs, m, n): """ :type strs: List[str] :type m: int for Zero :type n: int for One :rtype: int """ #dp[i][j]: 最多可有i個0與j個1的 最大子集數 dp=[ [0]*(n+1) for _ in range(m+1)] for str in strs: zero=0 one=0 for item in str: if item=='0': zero+=1 elif item=='1': one+=1 #填入dp 從大到小填!!!! for i in range(m,zero-1,-1): #不能低於zero的數量 for j in range(n,one-1,-1): #不能低於one的數量 dp[i][j]=max(dp[i][j],dp[i-zero][j-one]+1) return dp[m][n] strs = ["10","0001","111001","1","0"] m = 5 n = 3 result=Solution() ans=result.findMaxForm(strs,m,n) print(ans) ``` ## C++: ``` cpp= class Solution { public: int findMaxForm(vector<string>& strs, int m, int n) { vector<vector<int>> dp(m+1, vector<int>(n+1,0)); for (string item: strs){ int zero=0,one=0; for (char val: item){ (val=='0')? zero+=1: one+=1; } //dp for (int i=m; i>=zero; i--){ for (int j=n; j>=one; j--){ dp[i][j]=max(dp[i][j], dp[i-zero][j-one]+1); } } } return dp[m][n]; } }; ```