• leetcode_40 组合总数II


    1. 题意

    找到所有可能的组合数,只是不能重复选择同一元素。

    组合总数II

    2. 题解

    2.1 我的解法

    在leetcode39的基础上,再加上一个标记数组即可。

    class Solution {
    public:
        void gen(vector<vector<int>> &res, vector<int>& candidates, vector<int> &vis, 
            vector<int> &seq, int target)
            {
                if (target == 0) {
                    res.push_back(seq);
                    return ;
                }
                if ( target < 0)
                    return;
    
                int sz = candidates.size();
                for ( int i = 0;i < sz; ++i) {
                    
                    if (vis[i]) continue;
                    if (i && !vis[i - 1] && candidates[i] == candidates[i - 1])
                        continue;
                    if ( !seq.empty() && candidates[i] < seq[seq.size() - 1] )
                        continue;
                    
                    vis[i] = 1;
                    seq.push_back(candidates[i]);
                    gen(res, candidates, vis, seq, target - candidates[i]);
                    vis[i] =  0;
                    seq.pop_back();
    
    
                }
            }
    
        vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
            
    
            vector< vector<int> > ans;
            vector<int> seq;
            vector<int> vis(candidates.size(), 0);
    
            sort(candidates.begin(), candidates.end());
    
            gen(ans, candidates, vis, seq, target);
            
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    2.2 另一种可能的解法

    其实不需要标记数组,根据有序数组的特点和begin来进行去重。

    class Solution {
    public:
        void gen(vector<vector<int>> &res, vector<int>& candidates, 
            vector<int> &seq, int begin, int target)
            {
                if (target == 0) {
                    res.push_back(seq);
                    return ;
                }
                if ( target < 0)
                    return;
    
                int sz = candidates.size();
                for ( int i = begin;i < sz; ++i) {
                    
                    if ( i > begin && candidates[i] == candidates[i - 1])
                        continue;
    
                    seq.push_back(candidates[i]);
                    gen(res, candidates, seq, i + 1,target - candidates[i]);
                    seq.pop_back();
    
    
                }
            }
    
        vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
            
    
            vector< vector<int> > ans;
            vector<int> seq;
            vector<int> vis(candidates.size(), 0);
    
            sort(candidates.begin(), candidates.end());
    
            gen(ans, candidates,  seq, 0 ,target);
            
            return ans;
        }
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    2.3 官解

    统计相同数字出现的次数,一层内进行次数的枚举。

    class Solution {
    public:
        
        void gen(vector<vector<int>> &ans,vector<pair<int,int>> &freq,
            vector<int> &seq,int pos, int target)
        {
            if (target == 0) {
                ans.push_back(seq);
                return;
            }
    
            if ( pos == freq.size())
                return;
    
            int tm = min( target/freq[pos].first, freq[pos].second);
    
            for ( int i = 0; i <= tm; ++i) {
                gen(ans, freq, seq, pos + 1, target - freq[pos].first * i);
                seq.push_back(freq[pos].first);
            }
    
            for (int i = 0; i < tm + 1; ++i )
                seq.pop_back();
    
        }
    
        vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
            vector< vector<int>> ans;
            
            sort(candidates.begin(), candidates.end() );
    
            vector<pair<int,int>> freq;
            vector<int> seq;
    
            for (int v: candidates) {
                if (freq.empty() || freq.back().first != v)
                    freq.push_back(make_pair(v, 1));
                else
                    freq.back().second++;
            }
    
            gen(ans, freq, seq, 0, target);
    
            
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
  • 相关阅读:
    Java 流(Stream)、文件(File)和IO详解
    Python "爬虫"出发前的装备之二数据先行( Requests 模块)
    MongoDB——centOS7安装mongodb5.0.21版本服务端(图解版)
    亚马逊新手运营需要规避哪些风险?怎么分析竞争对手?——站斧浏览器
    如何用H5实现好玩的2048小游戏
    求解数组中N数之和最接近目标值的算法详解
    Redis使用lua脚本实现库存扣减
    百度隐藏“快照”功能:原因未知
    Anaconda常用操作(亲测有效果)
    list的模拟实现
  • 原文地址:https://blog.csdn.net/bdn_nbd/article/details/134085508