leetcode-474

90 阅读1分钟

题目描述:具体描述见原题。简单来说就是给定以个字符串数组和数字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
}

补充说明:背包问题也可以采用贪心解法。下午继续划水改论文。