这个题类似于背包问题,其中列表中的每个字符串可看作包含zeronum个0,onenum个1,且价值为1的商品,此时的求解换一种理解方式就是,给定可装m个0和n个1的背包,求可以把列表中的哪些字符串装入背包,保证zeronum的值<=m,onenum的值<=n。
解题代码都大同小异,但是有个问题不易理解,就是在求dp表时,为什么需要使用逆序求值
class Solution:
def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
dp = [[0]*(n+1) for _ in range(m+1)]
for i in strs:
zeronum = i.count('0')
onenum = i.count('1')
# 采用逆序是为了避免重复累加
for i in range(m, zeronum-1, -1):
for j in range(n, onenum-1, -1):
dp[i][j] = max(dp[i - zeronum][j - onenum] + 1, dp[i][j])
return dp[m][n]
下面给出一个动态求解dp表的过程
dp[i][j] = max(dp[i - zeronum][j - onenum] + 1, dp[i][j])
dp表的求解过程就是覆盖前一个表生成新表的过程,如果使用正序则会将覆盖值重复累加,造成所求解过大