class Solution {
public:
int findMaxForm(vector<string>& strs, int m, int n) {
}
};
474. 一和零
给你一个二进制字符串数组 strs
和两个整数 m
和 n
。
请你找出并返回 strs
的最大子集的长度,该子集中 最多 有 m
个 0
和 n
个 1
。
如果 x
的所有元素也是 y
的元素,集合 x
是集合 y
的 子集 。
示例 1:
输入:strs = ["10", "0001", "111001", "1", "0"], m = 5, n = 3 输出:4 解释:最多有 5 个 0 和 3 个 1 的最大子集是 {"10","0001","1","0"} ,因此答案是 4 。 其他满足题意但较小的子集包括 {"0001","1"} 和 {"10","1","0"} 。{"111001"} 不满足题意,因为它含 4 个 1 ,大于 n 的值 3 。
示例 2:
输入:strs = ["10", "0", "1"], m = 1, n = 1 输出:2 解释:最大的子集是 {"0", "1"} ,所以答案是 2 。
提示:
1 <= strs.length <= 600
1 <= strs[i].length <= 100
strs[i]
仅由 '0'
和 '1'
组成1 <= m, n <= 100
相似题目
原站题解
golang 解法, 执行用时: 28 ms, 内存消耗: 3.5 MB, 提交时间: 2022-11-28 13:52:08
func findMaxForm(strs []string, m int, n int) int { // 定义数组 dp := make([][]int, m+1) for i,_ := range dp { dp[i] = make([]int, n+1 ) } // 遍历 for i:=0;i<len(strs);i++ { zeroNum,oneNum := 0 , 0 //计算0,1 个数 //或者直接strings.Count(strs[i],"0") for _,v := range strs[i] { if v == '0' { zeroNum++ } } oneNum = len(strs[i])-zeroNum // 从后往前 遍历背包容量 for j:= m ; j >= zeroNum;j-- { for k:=n ; k >= oneNum;k-- { // 推导公式 dp[j][k] = max(dp[j][k],dp[j-zeroNum][k-oneNum]+1) } } //fmt.Println(dp) } return dp[m][n] } func max(a,b int) int { if a > b { return a } return b }
python3 解法, 执行用时: 2712 ms, 内存消耗: 15.1 MB, 提交时间: 2022-11-28 13:51:34
class Solution: def findMaxForm(self, strs: List[str], m: int, n: int) -> int: dp = [[0] * (n + 1) for _ in range(m + 1)] # 默认初始化0 # 遍历物品 for str in strs: ones = str.count('1') zeros = str.count('0') # 遍历背包容量且从后向前遍历! for i in range(m, zeros - 1, -1): for j in range(n, ones - 1, -1): dp[i][j] = max(dp[i][j], dp[i - zeros][j - ones] + 1) return dp[m][n]
javascript 解法, 执行用时: 364 ms, 内存消耗: 109.7 MB, 提交时间: 2022-11-28 13:50:34
/** * @param {string[]} strs * @param {number} m * @param {number} n * @return {number} */ var findMaxForm = function(strs, m, n) { const length = strs.length; const dp = new Array(length + 1).fill(0).map(() => new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0))); for (let i = 1; i <= length; i++) { const zerosOnes = getZerosOnes(strs[i - 1]); let zeros = zerosOnes[0], ones = zerosOnes[1]; for (let j = 0; j <= m; j++) { for (let k = 0; k <= n; k++) { dp[i][j][k] = dp[i - 1][j][k]; if (j >= zeros && k >= ones) { dp[i][j][k] = Math.max(dp[i][j][k], dp[i - 1][j - zeros][k - ones] + 1); } } } } return dp[length][m][n]; }; const getZerosOnes = (str) => { const zerosOnes = new Array(2).fill(0); const length = str.length; for (let i = 0; i < length; i++) { zerosOnes[str[i].charCodeAt() - '0'.charCodeAt()]++; } return zerosOnes; }
javascript 解法, 执行用时: 132 ms, 内存消耗: 43.1 MB, 提交时间: 2022-11-28 13:50:19
/** * @param {string[]} strs * @param {number} m * @param {number} n * @return {number} */ var findMaxForm = function(strs, m, n) { const dp = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0)); const length = strs.length; for (let i = 0; i < length; i++) { const zerosOnes = getZerosOnes(strs[i]); const zeros = zerosOnes[0], ones = zerosOnes[1]; for (let j = m; j >= zeros; j--) { for (let k = n; k >= ones; k--) { dp[j][k] = Math.max(dp[j][k], dp[j - zeros][k - ones] + 1); } } } return dp[m][n]; }; const getZerosOnes = (str) => { const zerosOnes = new Array(2).fill(0); const length = str.length; for (let i = 0; i < length; i++) { zerosOnes[str[i].charCodeAt() - '0'.charCodeAt()]++; } return zerosOnes; }
golang 解法, 执行用时: 20 ms, 内存消耗: 3.5 MB, 提交时间: 2022-11-28 13:49:58
/** * 由于 dp[i][][] 的每个元素值的计算只和 dp[i−1][][] 的元素值有关,因此可以使用滚动数组的方式, * 去掉 dp 的第一个维度,将空间复杂度优化到 O(mn)。 * 实现时,内层循环需采用倒序遍历的方式,这种方式保证转移来的是 dp[i−1][][] 中的元素值。 **/ func findMaxForm(strs []string, m, n int) int { dp := make([][]int, m+1) for i := range dp { dp[i] = make([]int, n+1) } for _, s := range strs { zeros := strings.Count(s, "0") ones := len(s) - zeros for j := m; j >= zeros; j-- { for k := n; k >= ones; k-- { dp[j][k] = max(dp[j][k], dp[j-zeros][k-ones]+1) } } } return dp[m][n] } func max(a, b int) int { if a > b { return a } return b }
golang 解法, 执行用时: 108 ms, 内存消耗: 74.4 MB, 提交时间: 2022-11-28 13:48:39
/** * 定义三维数组 dp,其中 dp[i][j][k] 表示在前 i 个字符串中,使用 j 个 0 和 k 个 1 的情况下最多可以得到的字符串数量。 * 假设数组 str 的长度为 l,则最终答案为 dp[l][m][n]。 **/ func findMaxForm(strs []string, m, n int) int { length := len(strs) dp := make([][][]int, length+1) for i := range dp { dp[i] = make([][]int, m+1) for j := range dp[i] { dp[i][j] = make([]int, n+1) } } for i, s := range strs { zeros := strings.Count(s, "0") ones := len(s) - zeros for j := 0; j <= m; j++ { for k := 0; k <= n; k++ { dp[i+1][j][k] = dp[i][j][k] if j >= zeros && k >= ones { dp[i+1][j][k] = max(dp[i+1][j][k], dp[i][j-zeros][k-ones]+1) } } } } return dp[length][m][n] } func max(a, b int) int { if a > b { return a } return b }