首页 > 编程语言 >回溯算法 组合问题(一)

回溯算法 组合问题(一)

时间:2022-10-10 23:13:01浏览次数:77  
标签:组合 int startIndex 算法 result 回溯 path size

题目来自leetcode 77题

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

你可以按 任何顺序 返回答案。

示例 1:
输入:n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]

示例 2:

输入:n = 1, k = 1
输出:[[1]]

组合问题的思考

回溯算法的步骤:确定返回值与参数-确定递归函数-确定单层递归-回溯(关键)

确定返回值与参数

首先设定两个全局变量,result 和 path:

vector<vector<int>> result;  
vector<int> path; //result是存储所有path组合的,path存储每一次取出的组合;

然后将条件中要用到的输入n值与k值,和另外再假设一个值startIndex,记录取出的一个数值,作为参数。

void backtracking(int n,int k,int startIndex);

递归函数与终止条件

void backtracking(int n ,int k ,int startIndex)

把这次回溯当作是一棵树,那么访问到叶子节点,也就是当path的大小刚好是k值,那么就可以结束一次取值;

if(path.size() == k) {
    result.push_back(path);
    return;}

单层循环

递归函数适用于纵向,往下遍历,for循环适用于横向循环;

for(int i = startIndex;i <=n ;i++) {
 path.push_back(i);//处理节点
 backtracking(n,k,i+1);//往下遍历
 path.pop_back();//回溯,撤销处理
 }

全部代码

class Solution {
   private:
      vector<vector<int>> result;  
      vector<int> path;
      void backtracking (int n,int k,int startIndex)
      {
        if(path.size() == k) { //终止条件
            result.push_back(path);
            return;}

        for(int i = startIndex;i <=n;i++)
        {
            path.push_back(i);//处理节点
            backtracking(n,k,i+1);//递归
            path.pop_back();//回溯,撤销处理的节点
        }
      }
    public:
      vector<vector<int>> combine(int n,int k)
      {
        result.clear();
        path.clear();
        backtracking(n,k,1);
        return result;
      }
};

剪枝优化

个人觉得,回溯算法上的剪枝优化,主要还是针对横向遍历时候的条件范围。
就是对于变量i在for循环中选择的起始位置:

for (int i = startIndex; i <= n; i++)
  • 已经选择的元素个数:path.size()
  • 还需要的元素个数:k-path.size()
  • 在集合n中至多要从该起始位置(n-(k-path.size()+1))开始遍历

所有优化之后的代码主要如下:

for(int i = startIndex; i <= n - (k-path.size()+1);i++)

小结

组合问题当中,使用回溯算法三部曲,其实也是递归三步法,只不过在递归的过程中,多了回溯的一步;
同时要注意,对于题目中的剪枝优化,主要着手的地方就是横向遍历的条件。

标签:组合,int,startIndex,算法,result,回溯,path,size
From: https://www.cnblogs.com/7xiaomao/p/16777770.html

相关文章

  • 牛客网高频算法题系列-BM19-寻找峰值
    牛客网高频算法题系列-BM19-寻找峰值题目描述给定一个长度为n的数组nums,请你找到峰值并返回其索引。数组可能包含多个峰值,在这种情况下,返回任何一个所在位置即可。峰......
  • 学习常用模型及算法1.模拟退火算法
    title:学习常用模型及算法1.模拟退火算法excerpt:学习数学建模常用模型及算法tags:[数学建模,matlab]categories:[学习,数学建模]index_img:https://picture-......
  • 学习常用模型及算法4.元胞自动机
    title:学习常用模型及算法4.元胞自动机excerpt:学习数学建模常用模型及算法tags:[数学建模,matlab]categories:[学习,数学建模]index_img:https://picture-st......
  • LeetCode算法笔记 350. 两个数组的交集 II
    importjunit.framework.TestCase;importjava.util.Arrays;importjava.util.HashMap;publicclassLeetCode03extendsTestCase{/***350.两个数组......
  • Class3 GMM以及EM算法
    title:Class3GMM以及EM算法excerpt:想让张宇老师教我机器学习!!!tags:[语音识别,ASR]categories:[学习,语音识别]index_img:https://picture-store-repository.......
  • AcWing算法提高课 容斥原理
    容斥原理的复杂度是2^n,一般n不会很大形如:  由于容斥原理一共有2^n中选法,可以用二进制枚举,1表示选择某个条件。然后将偶数个1的状态加起来,奇数个1的状态减去例题:ht......
  • qt容器与常用算法
    容器这些容器的使用方式和stl学的基本结构,使用方式是一样只要是数据就要使用容器,程序中的数据放在容器中方便增删改查。Qt库提供了一组通用的基于模板的容器类(contain......
  • 禁忌搜索算法实现经典VRP问题
    1.问题描述:        人工智能算法解决VRP问题。。        用禁忌搜寻算法实现VRP问题或者用启发式算法实现VRP问题只要不是GA算法约束任意只要是VRP问......
  • 深度学习/机器视觉/数字IC/FPGA/算法手撕代码目录总汇
    目录​​FPGA/数字IC手撕代码总汇​​​​常用算法手撕代码总汇​​​​FPGA工程师经典面试题​​​​数字IC经典面试题​​​​深度学习/人工智能/机器学习面试题​​​​......
  • COPE协议、RLNCBR算法功能实现
    1)接收节点数N变化,各节点丢包率P1=P2=…=Pn=0.08,节点数从2变化到10,增量为1,重传时间间隔为100Δt,作出平均传输次数随接收节点数变化的曲线图2)P1=P2=…=Pn且变化,从0.02变化到0.......