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

    题目

    给定两个整数 n 和 k,返回 1 ... 中所有可能的 k 个数的组合。

    分析

    本题属于回溯中的组合问题

    首先回溯问题的整体模板,如下(参考代码随想的Carl)

     1 void backtracking(参数) {
     2     if (终止条件) {
     3         存放结果;
     4         return;
     5     }
     6 
     7     for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
     8         处理节点;
     9         backtracking(路径,选择列表); // 递归
    10         回溯,撤销处理结果
    11     }
    12 }

    递归函数的参数不仅要有题目中的 N 和 K,还要记录本层递归中每次递归搜索的位置。每次从集合中选取元素,可选择的范围随着选择的进行而收缩,调整可选择的范围,就是要靠startIndex

     相当于对原本的搜索树修剪,越搜索树宽度越窄,因为有些结果在之前就搜索过了。

    代码

    class Solution {
    public:
        vector<int>path;//存放单条路径的结果
        vector<vector<int>>res; //存放路径结果的集合
    
        void backtracking(int n,int k,int startIndex){
            //终止条件
            if(path.size() == k){
                res.push_back(path);//存放结果
                return;
            }
            //for循环对搜索树横向遍历,递归对搜索树纵向遍历
            //for循环的开始搜索位置是strartIndex
            for(int i = startIndex;i <= n;i++){
                path.push_back(i);//对节点进行处理
                backtracking(n,k,i+1);//递归
                path.pop_back();//回溯,撤销对节点的处理
            }
        }
        vector<vector<int>> combine(int n, int k) {
            backtracking(n,k,1);
            return res;
        }
    };

    其实这样并不算最优,因为还可以将搜索树进行剪枝

     for 循环选择的起始位置之后的元素个数 已经不足我们需要的元素个数,就没有必要搜索,直接剪掉。

    所以优化后的代码如下:

     1 class Solution {
     2 private:
     3     vector<vector<int>> result; 
     4     vector<int> path;
     5     void backtracking(int n, int k, int startIndex) {
     6         if (path.size() == k) {
     7             result.push_back(path);
     8             return;
     9         }
    10         for (int i = startIndex; i <= n - (k - path.size()) + 1; i++) { // 优化的地方
    11             path.push_back(i); // 处理节点 
    12             backtracking(n, k, i + 1);
    13             path.pop_back(); // 回溯,撤销处理的节点
    14         }
    15     }
    16 public:
    17 
    18     vector<vector<int>> combine(int n, int k) {
    19         backtracking(n, k, 1);
    20         return result;
    21     }
    22 };
  • 相关阅读:
    团队作业第四次—项目系统设计与数据库设计
    团队Github实战训练
    第三次团队作业(需求分析)
    团队作业——UML设计
    项目介绍
    Happy Tree Friends——团队展示
    Alpha冲刺 (1/9)
    团队作业第四次—项目系统设计与数据库设计
    团队Github实战训练
    团队作业——需求分析
  • 原文地址:https://www.cnblogs.com/fresh-coder/p/14338984.html
Copyright © 2011-2022 走看看