474.一和零

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ones-and-zeroes
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

物品一个一个尝试,容量一点一点尝试,每个物品分类讨论的标准是:选与不选。

题目是从一个数组中按一定的选取方式得到目标target,那么尝试将题目进行转化。

这道题得物品是一个字符串,物品的重量有两个一个是0的个数、一个是1的个数,这道题求的是最大子集的长度,那么每个字符串的价值就是1。背包的重量也是从两个维度来考虑,最多 有 m 个 0和 n 个 1。每个物品只能取一次,那么也是个01背包。

1.确定dp数组以及下标的含义
dp[i][j] 最大子集的长度,该子集中 最多 有 i 个 0 和 j 个 1 。

2.确定递推公式
每个字符串0的个数为ZoreNum,1的个数为OneNum。
dp[i][j]=Math.max(dp[i-ZoreNum][j-OneNum]+1,dp[i][j])

3.dp数组如何初始化
价值都是正数,所以初始化为0就行了。

4.确定遍历顺序
先从左到右遍历物品,再从右到左遍历背包。在遍历物品的同时,可以统计这个字符串中0和1的个数。

for(String str:strs){
  //统计0和1的个数
  int ZoreNum=0,OneNum=0;
  for(int i=0;i<str.length();i++){
	  if(str.charAt(i)=='0')ZoreNum++;
	  else OneNum++;
  }
	//从右往左遍历背包
	for(int i=m;i>=ZoreNum;i--){
		for(int j=n;j>=OneNum;j--){
			dp[i][j]=Math.max(dp[i-ZoreNum][j-OneNum]+1,dp[i][j]);
		}
	}
}

5.举例推导dp数组
strs = ["10", "0", "1"], m = 1, n = 1

image

代码

class Solution {
    public int findMaxForm(String[] strs, int m, int n) {
        int [][] dp = new int[m+1][n+1];
        for(String str:strs){
             //统计0和1的个数
            int ZoreNum=0,OneNum=0;
            for(int i=0;i<str.length();i++){
	            if(str.charAt(i)=='0')ZoreNum++;
	            else OneNum++;
            }
	        //从右往左遍历背包
	        for(int i=m;i>=ZoreNum;i--){
	        	for(int j=n;j>=OneNum;j--){
			    dp[i][j]=Math.max(dp[i-ZoreNum][j-OneNum]+1,dp[i][j]);
		    }
    	    }
        }
            return dp[m][n];
        }
    }

posted @ 2021-09-26 12:01  rananie  阅读(41)  评论(0编辑  收藏  举报