组合(力扣77)

从这道题开始,我们正式进入回溯算法的学习。之前在二叉树中只是接触到了一丢丢,而这里我们将使用回溯算法解决很多经典问题。

那么这道题是如何使用回溯算法的呢?在讲回溯之前,先说明一下此题是如何递归的。毕竟回溯递归不分家,必须先有递归,才会有回溯。而这里的递归就是在缩小范围后的集合中使用for循环选择数字。举个例子:最开始的集合有1,2,3,4,那么我们第一次一定是从这个集合中选一个数。为了保证之后不重复选择1,我们下一步一定是从2,3,4这个集合中选一个数,以此类推。我们可以发现被选择集合的范围在不断缩小。还有就是,需要考虑组合的无序性(1,2和2,1是相同的组合),那么每一层递归中的for循环的遍历范围都要改变,这就需要设置一个变量来控制。接下来讲一下回溯,我们需要写一个for循环将递归函数包起来,这个for循环的作用是遍历当前集合的所有数,假设在第一个集合中我们已经选了1这个数,然后递归选择第二个数,那么在选择第二个数的递归函数结束之后,我们可以将1弹出存储组合的数组,并通过for循环选择第一个集合中的第二个数,这样就得到了其他组合情况。这道题大家可以当做模版题记下来,之后的回溯算法的代码风格都与这道题大差不差。可以结合我下面的代码及注释理解这道题。

代码及注释如下:

复制代码
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;
    }
};
相关推荐
GalaxyPokemon1 小时前
归并排序:分治思想的高效排序
数据结构·算法·排序算法
ThreeYear_s1 小时前
基于FPGA的PID算法学习———实现PI比例控制算法
学习·算法·fpga开发
Coding小公仔3 小时前
LeetCode 240 搜索二维矩阵 II
算法·leetcode·矩阵
C++chaofan3 小时前
74. 搜索二维矩阵
java·算法·leetcode·矩阵
青小莫4 小时前
数据结构-C语言-链表OJ
c语言·数据结构·链表
Studying 开龙wu4 小时前
机器学习监督学习实战五:六种算法对声呐回波信号进行分类
学习·算法·机器学习
Mi Manchi264 小时前
力扣热题100之二叉树的层序遍历
python·算法·leetcode
wu~9704 小时前
leetcode:42. 接雨水(秒变简单题)
算法·leetcode·职场和发展
zhurui_xiaozhuzaizai6 小时前
模型训练-关于token【低概率token, 高熵token】
人工智能·算法·自然语言处理