题目描述:具体描述见原题。简单来说就是给定以个字符串数组和数字m,n,其中字符串内所有字符都由0和1组成,取出尽可能多的字符串,使得字符串中“0”的总数<=n,“1”的总数<=m。
集体思路:这是一道典型背包问题,使用二维数组存储更新过程值。i代表0个数,j代表1个数。res[i][j]代表上限为i个0和j个1的时候包含最多字符串数量。每加入一个字符串就刷新res[i][j]的值,假设新加入字符串中包含m个“0”,n个“1”。状态转移方程为res[i][j]=max(res[i][j],res[i-m][j-n]+1)。具体过程见代码。
具体代码:
func findMaxForm(strs []string, m int, n int) int {
res := make([][]int, m+1)
for i := 0; i < len(res); i++ {
res[i] = make([]int, n+1) // 初始换二维数组
}
for _, s := range strs{
one := strings.Count(s, "1") // 当新字符串加入时,获取字符串中0和1的个数
zero := strings.Count(s, "0")
if one > n || zero > m {
continue
}
for i := m; i >= zero; i-- {
for j := n; j >= one; j-- {
res[i][j] = max(res[i][j], res[i-zero][j-one]+1) // 根据状态转移方程跟新res,注意两层循环判断条件
}
}
}
return res[m][n]
}
func max(x, y int) int {
if x > y {
return x
}
return y
}
补充说明:背包问题也可以采用贪心解法。下午继续划水改论文。