【开始刷LeetCode】474. 一和零

一、绪

本篇文章主要用到动态规划的思想,并且这个问题和动态规划中经典的01背包问题类似,所以我们可以套用01背包的解法求解这个问题。但这个问题要比基本的01背包要复杂一点,原来的01背包只需要考虑重量一个限制因素,而这道题需要考虑两个限制因素。

01背包的问题解法我也在另外一篇博客里进行了分析解释,详情可跳转链接: 【动态规划】01背包问题(装还是不装,老子不装啦。。。老子就是菜).

二、一和零

链接: 474. 一和零.

(一)题目描述

解释
给你一个二进制字符串数组 strs 和两个整数 m 和 n 。
请你找出并返回 strs 的最大子集的长度,该子集中 最多 有 m 个 0 和 n 个 1 。
如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集 。

示例一:

输入: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 。

示例二:

输入:strs = ["10", "0", "1"], m = 1, n = 1
输出:2
解释:最大的子集是 {"0", "1"} ,所以答案是 2 。

解题思路
如果对经典01背包问题有认知,那么这道题与01背包问题的区别就是比01背包只需要考虑重量这一限制元素要多一个限制元素。打个比喻,01背包原本只需要考虑物品的重量,现在我要同时考虑物品的重量和体积。

所以我们解决问题就需要用到一个三维数组,利用01背包解决问题的算法思想我们就能解决这个问题。
在这里插入图片描述
算法公式如下:
在这里插入图片描述

(二)AC代码

以下的代码,我是优化了空间的,只用二维的dp数组。

int findMaxForm(char ** strs, int strsSize, int m, int n){

    int Wm[strsSize],Wn[strsSize];

    for(int i=0;i<strsSize;i++){
        int ones=0,zeroes=0;
        for(int j=0;j<strlen(strs[i]);j++){
            if(strs[i][j]=='1'){
                ones++;
            }else{
                zeroes++;
            }
        }
        Wm[i]=zeroes;
        Wn[i]=ones;
    }

    int dp[m+1][n+1];
    memset(dp,0,sizeof(dp));

    for(int k=0;k<strsSize;k++){
        for(int i=m;i>=0;i--){
            for(int j=n;j>=0;j--){
                if(i>=Wm[k]&&j>=Wn[k]){
                    if(dp[i][j]<dp[i-Wm[k]][j-Wn[k]]+1){
                        dp[i][j]=dp[i-Wm[k]][j-Wn[k]]+1;
                    }
                }
            }
        }
    }

    return dp[m][n];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

peng_YuJun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值