回溯算法问题

回溯算法问题

通用模板:

void backtracking(参数) {
    if (终止条件) {   //一般到终止条件只要确保跟结果对的参数正确就行,不需要考虑其他参数,比如是否越界之类的。
        存放结果;
        return;
    }
    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) { //一般这里就可以做剪枝
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

例子1:

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

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

#include <iostream>
#include <vector>
using namespace std;
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(); // 回溯,撤销处理的节点
    }
}
vector<vector<int>> combine(int targetSum, int k) {
    result.clear(); // 可以不写
    path.clear();   // 可以不写
    backtracking(targetSum, k, 0, 1);
    return result;
}
void printvv(vector<vector<int>> matrix) {
    for (size_t i = 0; i < matrix.size(); ++i) {
        for (size_t j = 0; j < matrix[i].size(); ++j) {
            std::cout << matrix[i][j] << " ";
        }
        std::cout << std::endl;
    }
}

int main() {
    vector<vector<int>> matrix;
    printvv(combine(4,2));

    return 0;
}

例子2:

找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。

说明:

  • 所有数字都是正整数。
  • 解集不能包含重复的组合。

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

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

#include <iostream>
#include <vector>
using namespace std;
vector<vector<int>> result; // 存放符合条件结果的集合
vector<int> path; // 用来存放符合条件结果

void backtracking(int targetSum, int k, int sum, int startIndex) {
    if (path.size() == k) {
        //std::cout << startIndex << ":" << k << std::endl;

        if (targetSum == sum) {
            result.push_back(path);
            
        }
        return;
    }
    for (int i = startIndex; i <= 9; i++) {
        //std::cout << i << std::endl;
        path.push_back(i);
        backtracking(targetSum, k, sum + i, i + 1);
        path.pop_back();
    }
}

vector<vector<int>> combine(int targetSum, int k) {
    result.clear(); // 可以不写
    path.clear();   // 可以不写
    backtracking(targetSum, k, 0, 1);
    return result;
}
void printvv(vector<vector<int>> matrix) {
    for (size_t i = 0; i < matrix.size(); ++i) {
        for (size_t j = 0; j < matrix[i].size(); ++j) {
            std::cout << matrix[i][j] << " ";
        }
        std::cout << std::endl;
    }
}

int main() {
    vector<vector<int>> matrix;
    printvv(combine(22,6));
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值