LeetCode 组合、组合总和(I ~ IV)(C++)(回溯法、图的深度优先遍历)

这篇博客详细介绍了如何使用C++的回溯法来解决LeetCode上的组合与组合总和系列问题,包括组合、组合综合、组合总和II、组合总和III和组合总和IV。博主通过问题描述、解题思路和代码实现,阐述了如何运用深度优先遍历的思想来解决这类问题,并提供了多个代码实现示例及运行截图。
摘要由CSDN通过智能技术生成

1、组合

问题描述

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

示例:

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

解题思路

  • 该题目使用 回溯(su)法也等价于树(图)的深度优先遍历算法来求解。
  • 分别定义用于存储最终结果的二维vector容器和存储每个结点的一维vector容器。二维容器用于将每次一维容器装满元素后的压入。而大小为k的一维容器用于装大小为k的个数的组合。当数量满足为k的时候,压入到二维容器中。
  • 核心思想是图的深度优先遍历。当一维容器大小满足k个时,需要结点回退,重新将下一个新的元素压入一维容器中。再加上for循环,可以保证遍历到所有符合情况且不重复的元素。
  • 考虑到k值问题,在遍历过程中,n个结点剩余小于k个结点没有遍历时,可以停止遍历,因为此时已不满足k个元素成为一个新的结点压入到二维数组中。这是一种剪枝的思想。

代码实现(1)

class Solution {
   
public:
    vector< vector<int> > res; // 存放符合条件结果的集合
    vector<int> path; // 用来存放符合条件结果
    void backtracking(int startIndex, int n, int k) {
   
        if (path.size() == k) {
   
            res.push_back(path);
            return;
        }
        // 这个for循环有讲究,组合的时候 要用startIndex,排列的时候就要从0开始
        for (int i = startIndex; i <= n - (k - path.size()) + 1; i++) {
   
            path.push_back(i); // 处理节点 
            backtracking(i + 1, n, k);
            path.pop_back(); // 回溯,撤销处理的节点
        }
    }
    vector<vector<int>> combine(int n, int k) {
   
        backtracking(1, n, k);
        return res;
    }
};

运行截图

在这里插入图片描述

代码实现(2)

  • 下述代码和上面的代码思想是一致的。
class Solution {
   
public:
    vector< vector<int> > ans;
    vector<int> temp;
    void deepFirstTraverse(int index, int n, int k){
   
        if(temp.size() == k){
   
            ans.push_back(temp);
            return;
        }
        if(temp.size() + (n - index + 1) < k)
            return;
        temp.push_back(index);
        deepFirstTraverse(index + 1, n, k);
        temp.pop_back();
        deepFirstTraverse(index + 1, n, k);
    }
    vector<vector<int>> combine(int n, int k) {
   
        deepFirstTraverse(1, n, k);
        return ans;
    }
};

运行截图

在这里插入图片描述

2、组合综合

问题描述

给定一个无重复元素的数组 candidates和一个目标数 target,找出 candidates中所有可以使数字和为target的组合。

candidates中的数字

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值