474 一和零 力扣每日一题

欢迎关注微信公众号:【没伞的孩子拼命跑】 和我的小伙伴们一块坚持打卡变大牛吧。

题目要求 

题目解析

题目说的是给你m个0,n个1,让你求给定的字符串中,符合0的个数小于等于m,1的个数小于等于n的字符串的个数最大为多少?

解题思路

首先要想这个题的解题方法是什么?之前提到过凡是求最大,最小的,一般都是用动态规划。大家如果做过背包问题,其实对于这个题目还是有感觉的。背包问题是让装的东西小于V,而这个题是让0小于m,1小于n两个条件。经典的背包问题是用两个维度的数组,所以现在是用三个维度的数组

定义状态:dp[i][j][k] 表示输入字符串在子区间 [0, i] 能够使用 j 个 0 和 k 个 1 的字符串的最大数量。

dp[i-1][j][k] 不选择当前考虑的字符串,至少是这个数值

dp[i][j][k]={dp[i−1][j][k],dp[i−1][j−当前字符串使用0的个数][k−当前字符串使用1的个数]+1 选择当前考虑的字符串。

其实你会发现,前行只参考了上一行的值,因此可以使用滚动数组,也可以从后向前赋值。

AC代码和详细注释如下

//C++题解 //从后往前赋值
class Solution {
public:
    int findMaxForm(vector<string>& strs, int m, int n) {
        vector<vector<int>>dp(m+1,vector<int>(n+1,0));
        int num1=0;//1的个数
        int num0=0;//2的个数
        for(auto str:strs)
        {
            num0=0;
            num1=0;
            //得到每个字符串中1的个数和0的个数
            for(int i = 0;i<str.size();i++)
            {
                if(str[i]=='0')
                    num0++;
                else num1++;
            }
          //实现时,内层循环需采用倒序遍历的方式,这种方式保证转移来的是 
          //dp[i-1][][]dp[i−1][][] 中的元素值
            for(int i = m;i>=num0;i--)
            {
                for(int j = n;j>=num1;j--)
                {
                    dp[i][j] = max(dp[i][j],dp[i-num0][j-num1]+1);
                }
            }
            
        }
        return dp[m][n];
    }
};

通过情况

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值