跳至主要內容

0474. 一和零

ITCharge大约 3 分钟

0474. 一和零open in new window

  • 标签:数组、字符串、动态规划
  • 难度:中等

题目链接

题目大意

描述:给定一个二进制字符串数组 strsstrs,以及两个整数 mmnn

要求:找出并返回 strsstrs 的最大子集的大小,该子集中最多有 mm00nn11

说明

  • 如果 xx 的所有元素也是 yy 的元素,集合 xx 是集合 yy 的子集。
  • 1strs.length6001 \le strs.length \le 600
  • 1strs[i].length1001 \le strs[i].length \le 100
  • strs[i]strs[i] 仅由 '0''1' 组成。
  • 1m,n1001 \le m, n \le 100

示例

  • 示例 1:
输入:strs = ["10", "0001", "111001", "1", "0"], m = 5, n = 3
输出:4
解释:最多有 5031 的最大子集是 {"10","0001","1","0"} ,因此答案是 4 。
其他满足题意但较小的子集包括 {"0001","1"}{"10","1","0"}{"111001"} 不满足题意,因为它含 41 ,大于 n 的值 3
  • 示例 2:
输入:strs = ["10", "0", "1"], m = 1, n = 1
输出:2
解释:最大的子集是 {"0", "1"} ,所以答案是 2

解题思路

思路 1:动态规划

这道题可以转换为「二维 0-1 背包问题」来做。

00 的个数和 11 的个数视作一个二维背包的容量。每一个字符串都当做是一件物品,其成本为字符串中 11 的数量和 00 的数量,每个字符串的价值为 11

1. 划分阶段

按照物品的序号、当前背包的载重上限进行阶段划分。

2. 定义状态

定义状态 dp[i][j]dp[i][j] 表示为:最多有 ii00jj11 的字符串 strsstrs 的最大子集的大小。

3. 状态转移方程

填满最多由 ii00jj11 构成的二维背包的最多物品数为下面两种情况中的最大值:

  • 使用之前字符串填满容量为 izeronumi - zero\underline{}numjonenumj - one\underline{}num 的背包的物品数 + 当前字符串价值
  • 选择之前字符串填满容量为 iijj 的物品数。

则状态转移方程为:dp[i][j]=max(dp[i][j],dp[izeronum][jonenum]+1)dp[i][j] = max(dp[i][j], dp[i - zero\underline{}num][j - one\underline{}num] + 1)

4. 初始条件
  • 无论有多少个 00,多少个 11,只要不选 00,也不选 11,则最大子集的大小为 00
5. 最终结果

根据我们之前定义的状态,dp[i][j]dp[i][j] 表示为:最多有 ii00jj11 的字符串 strsstrs 的最大子集的大小。所以最终结果为 dp[m][n]dp[m][n]

思路 1:代码

class Solution:
    def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
        dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)]
        
        for str in strs:
            one_num = 0
            zero_num = 0
            for ch in str:
                if ch == '0':
                    zero_num += 1
                else:
                    one_num += 1
            for i in range(m, zero_num - 1, -1):
                for j in range(n, one_num - 1, -1):
                    dp[i][j] = max(dp[i][j], dp[i - zero_num][j - one_num] + 1)

        return dp[m][n]

思路 1:复杂度分析

  • 时间复杂度O(l×m×n)O(l \times m \times n),其中 ll 为字符串 strsstrs 的长度。
  • 空间复杂度O(m×n)O(m \times n)