ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

C语言重构【474】一和零

2021-01-16 18:33:15  阅读:225  来源: 互联网

标签:重构 int len C语言 strs vector 子集 474 dp


文章目录

所有题目源代码:Git地址

题目

给你一个二进制字符串数组 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 。

方案:

  • 思路在注释中,这里简单讲下,我认为这是一道二维动态规划的题(虽然是三维dp数组),其公式如下:参考地址
    在这里插入图片描述
  • 需要注意的是i=0的第一个二维一定得初始化为0,我这里本来想用三维vector,结果不知道咋初始化~,后来还是用了原始方法
  • 值得一提的是,可以先把每个字符串的0,1个数事先算出来,再调用就可以减少很多计算量,同时也简化了题目。
class Solution
{
public:
    int findMaxForm(vector<string> &strs, int m, int n)
    {
        int len = strs.size();
        //dp[i][j][k] i=len;j=m;k=n;
        // vector<vector<vector<int>>> dp(len+1,vector<int>(m+1,vector<int>(n+1)));
        int dp[len + 1][m + 1][n + 1];
        for (int j = 0; j <= m; j++)
            for (int k = 0; k <= n; k++)
                dp[0][j][k] = 0;

        //先数清每个串0,1个数
        // vector<vector<int>> tmp(len,vector<int>(2,0));
        int tmp[len][2];
        for (int i = 0; i < len; i++)
        {
            //count
            int cn = 0, cm = 0;
            for (int j = 0; j < strs[i].size(); j++)
                if (strs[i][j] == '0')
                    cm++;
                else if (strs[i][j] == '1')
                    cn++;
            tmp[i][0] = cm;
            tmp[i][1] = cn;
        }
        //再填dp
        //dp[i][j][k]   =dp[i-1][j][k]       (不放)
        //              =dp[i-1][j-m][k-n]+1 (放,这里注意需要考虑jk比mn小的问题,mn是某个字符串01个数)
        for (int i = 1; i <= len; i++)
            for (int j = 0; j <= m; j++)
                for (int k = 0; k <= n; k++)
                    if (k < tmp[i - 1][1] || j < tmp[i - 1][0])
                        //背包空间不够,不能放
                        dp[i][j][k] = dp[i - 1][j][k];
                    else 
                        //背包空间足够,可以考虑放
                        dp[i][j][k] = max(dp[i - 1][j][k], dp[i - 1][j - tmp[i - 1][0]][k - tmp[i - 1][1]] + 1);
        return dp[len][m][n];
    }
};
复杂度计算
  • 时间复杂度:O(lenmn)
  • 空间复杂度:O(lenmn);其他的计数为小头(2*len)

标签:重构,int,len,C语言,strs,vector,子集,474,dp
来源: https://blog.csdn.net/symuamua/article/details/112719737

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有