题解 | 一和零

alt

题干解析

题设给予一个字符串数组strs,该数组中每个字符串只包含0,和1。要求我们找到一个strs的子集,子集中所有字符串的01字符数分别不超过m与n。求可找到的最大子集的势(子集中元素个数)。

算法思路

本题本质上可以看作有两项限制的0/1背包问题:

我们设定状态值dp[i][j][k],考虑前i个字符串,表示0的个数为j,1的个数为k的子数组中元素的个数。由此我们能够得到状态转移方程如下:

其中dp[i-1][j][k]表示不选择第i个字符串的情况,dp[i-1][j-cnt_0][k-cnt_1] + 1是选择的情况,二者取大。

同时由于DP状态转移过程中,只涉及i与i-1,因此可以只使用一个二维数组解决问题,优化内存占用。

实现代码

class Solution {
public:
    int findMaxForm(vector<string>& strs, int m, int n) {
        vector<vector<int>> dp(m + 1, vector<int>(n + 1));
        for (auto &s : strs) {
            int cnt0 = count(s.begin(), s.end(), '0');
            int cnt1 = s.size() - cnt0;
            for (int j = m; j >= cnt0; --j) {
                for (int k = n; k >= cnt1; --k) {
                    dp[j][k] = max(dp[j][k], dp[j - cnt0][k - cnt1] + 1);
                }
            }
        }
        return dp[m][n];
    }
};

复杂度分析

  • 时间复杂度:,其中t表示strs数组元素个数,表示第i+1个字符串的长度
  • 空间复杂度:
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务