zoukankan      html  css  js  c++  java
  • LeetCode77. 组合

    DFS回溯,从左至右选数,加入一个一维数组oneCombination中,当oneCombination的大小等于k,表示已经选了k个数,
    将oneCombination压入结果数组res中。

    DFS的函数签名可以写为void DFS(int n, int k, int startPos, vector& oneCombination, vector<vector>& res)
    表示从1~n里选k个数,当前组合的起始位置为startPos,当前组合记录在一维数组oneCombination中。
    这样,只要当前组合oneCombination的大小小于k,我们就可以继续枚举下一个数:DFS(n, k, i + 1, oneCombination, res) (1 <= i <= n)
    当oneCombination的大小等于k时,表示选出了k个数,将当前组合压入res中,递归会回到上一层,也就是只选好了k-1个数的情况(恢复现场),然后
    继续判断第k个数能不能选其他的,再上层的递归同理。

    递归结束时就找到了所有的k个数的组合,返回结果数组res即可。

    由于我们是startPos是从左往右的,且当前组合选的数都必须比startPos大(我们选出的组合都是升序的),所以避免了重复,是OK的。

    class Solution {
    vector<vector<int>> res;
    vector<int> oneCombination;
    public:
        vector<vector<int>> combine(int n, int k) {
            DFS(n, k, 1, oneCombination, res);
            return res;    
        }
        void DFS(int n, int k, int startPos, vector<int>& oneCombination, vector<vector<int>>& res) {
            if(oneCombination.size() == k) {                        //当前组合数量已经为k了,甭递归了,res数组中赶紧压入当前组合
                res.push_back(oneCombination);                      //然后回到上一层递归去,搜索第k个数能否是别的数
                return ;
            }
            for(int i = startPos; i <= n; ++i) {                    //当前组合的数必须都大于等于startPos,好马不吃回头草
                oneCombination.push_back(i);                      
                DFS(n, k, i + 1, oneCombination, res);              //当前组合压入了一个数i,继续看看下一个数能放啥
                oneCombination.pop_back();                          //有push_back()必然有pop_back(),回溯一定是对称的!!!! 因为要恢复现场
            }
        }
    };
    
  • 相关阅读:
    Vmware虚拟机的单用户模式
    Xshell密钥认证
    PuTTY密钥认证
    CentOS 7在NAT模式下配置静态IP
    使用OllyDbg破解EasyCrackMe
    2017 计蒜之道 初赛 第五场 A. UCloud 机房的网络搭建
    2017 计蒜之道 初赛 第五场 A. UCloud 机房的网络搭建
    Kafka常用命令
    选择器和层叠
    语义化
  • 原文地址:https://www.cnblogs.com/linrj/p/13237310.html
Copyright © 2011-2022 走看看