LeetCode:474

这篇博客介绍了如何使用动态规划解决一个01背包问题的变种,即在给定的二进制字符串数组中找到最大子集,使得子集中0不超过m个且1不超过n个。博主通过定义二维dp数组来存储不同0和1数量的最大子集大小,并从后向前遍历字符串,避免重复计数。最后返回dp[m][n]作为结果。
摘要由CSDN通过智能技术生成

题目 474. 一和零

给你一个二进制字符串数组 strs 和两个整数 m 和 n 。

请你找出并返回 strs 的最大子集的大小,该子集中 最多 有 m 个 0 和 n 个 1 。

如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集 。

题解

动态规划,01背包问题的变种
将问题分解为二维的,以dp[m][n] 表示有m个0和n个1的最大子集的大小,通过遍历数组,对每个字符串的zeroNum和oneNum进行统计,并统计包括当前字符串0,1数目的并且符合0,1数目分别小于m,n条件的各个子集的大小。

注意要从后向前遍历,否则一个字符串可能被多次统计

代码

class Solution
{
public:
    int count_0(const string &str)
    {
        int res(0);
        for (auto i : str)
        {
            if (i == '0')
            {
                res++;
            }
        }
        return res;
    }
    int count_1(const string &str)
    {
        return str.size() - count_0(str);
    }
    int findMaxForm(vector<string> &strs, int m, int n)
    {
        vector<vector<int>>recs(m+1,vector<int>(n+1,0));
        for(auto s:strs)
        {
            int a = count_0(s);
            int b = count_1(s);
            for(int i = m;i>=a;--i)
            {
                for(int j = n;j>=b;--j)
                {
                    recs[i][j] = max(recs[i][j],recs[i-a][j-b]+1);
                }
            }
        }
        return recs[m][n];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值