首页 > 编程语言 >回溯算法详解

回溯算法详解

时间:2024-06-01 14:31:27浏览次数:26  
标签:std int res back 算法 vector 回溯 path 详解

回溯

回溯概念

题解

组合问题

LeetCode-77 组合

LeetCode-77 组合

题目描述:

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

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

题目思路:

Alt

代码
#include <iostream>
#include <vector>
#include <deque>

class Solution {
public:
    std::vector<std::vector<int>> combine(int n, int k) {
        std::vector<std::vector<int>> res;
        if (k <= 0 || n < k) {
            return res;
        }
        std::deque<int> path;
        dfs(n, k, 1, path, res);
        return res;
    }

private:
    void dfs(int n, int k, int begin, std::deque<int>& path, std::vector<std::vector<int>>& res) {
        if (path.size() == k) {
            res.push_back(std::vector<int>(path.begin(), path.end()));
            return;
        }
        for (int i = begin; i <= n; i++) {
            path.push_back(i);
            printDeque(path, "递归之前 => ");
            dfs(n, k, i + 1, path, res);
            path.pop_back();
            printDeque(path, "递归之后 => ");
        }
    }

    void printDeque(const std::deque<int>& path, const std::string& prefix) {
        std::cout << prefix;
        for(const auto& num : path) {
            std::cout << num << " ";
        }
        std::cout << std::endl;
    }
};

int main() {
    Solution solution;
    int n = 4;
    int k = 2;
    std::vector<std::vector<int>> res = solution.combine(n, k);
    for(const auto& list : res) {
        std::cout << "[";
        for(const auto& num : list) {
            std::cout << num << " ";
        }
        std::cout << "]" << std::endl;
    }
    return 0;
}

before => 1 
before => 1 2 
after => 1 
before => 1 3 
after => 1 
before => 1 4 
after => 1 
after => 
before => 2
before => 2 3
after => 2
before => 2 4
after => 2
after =>
before => 3
before => 3 4
after => 3
after =>
before => 4
after =>
[1 2 ]
[1 3 ]
[1 4 ]
[2 3 ]
[2 4 ]
[3 4 ]

LeetCode-216 组合Ⅲ

LeetCode-216 组合Ⅲ

题目描述

找出所有相加之和为 nk 个数的组合,且满足下列条件:

  • 只使用数字1到9
  • 每个数字 最多使用一次
  • 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
题目思路
代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>

using namespace std;


class Solution {
public:
    vector<vector<int>> combinationSum3(int k, int n) {
        dfs(k, n, 1);
        return res;
    }
private:
    vector<vector<int>> res;
    vector<int> path;
    void dfs(int k, int n, int index);
    static inline void printVector(const vector<int>& v, std::string prefix) {
        cout << prefix;
        for (const auto elem : v) {
            cout << elem << " ";
        }
        cout << endl;
    }
};

void Solution::dfs(int k, int n, int index) {
    if (path.size() == k) {
        if (accumulate(path.begin(), path.end(), 0) == n) res.push_back(path);
        return;
    }
    for (int i = index; i <= 9; i++) {
        printVector(path, "before");
        path.push_back(i);
        // if (path.size() > k) {   // 无效剪枝
        //     path.pop_back();
        //     return;
        // }
        if (accumulate(path.begin(), path.end(), 0) > n) {  // 剪枝
            path.pop_back();
            return;
        }
        dfs(k, n, i+1);
        printVector(path, "after");
        path.pop_back();
    }
}

int main() {
    Solution solution;
    int k = 3, n = 7;

    vector<vector<int>> v = solution.combinationSum3(k, n);
    for(const auto& list : v) {
        std::cout << "[";
        for(const auto& num : list) {
            std::cout << num << " ";
        }
        std::cout << "]" << std::endl;
    }
    return 0;
}

LeetCode-39 组合总数

题目描述:

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

解题思路
代码
class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        back_tracking(candidates, target, 0);
        return res;
    }
private:
    vector<vector<int>> res;
    vector<int> path;

    void back_tracking(vector<int>& candidates, int target, int index) {
        if (accumulate(path.begin(), path.end(), 0) > target) {
            return;
        }
        if (accumulate(path.begin(), path.end(), 0) == target) {
            res.push_back(path);
            return;
        } 
        for (int i = index; i < candidates.size(); i++) {
            path.push_back(candidates[i]);
            back_tracking(candidates, target, i);
            path.pop_back();
        }
    }
};

排列问题

LeetCode-46 全排列

题目描述
解题思路
代码
class Solution {
public:
/**
* 回溯算法相关知识点
* 回溯算法适用: 求解搜索问题和优化问题
* 搜索空间是树,结点对应部分解向量,可行解在叶结点上
* 搜索过程:采用系统的方法隐含的遍历搜索树
* 搜索策略: 深度优先, 宽度优先, 宽深结合, 函数优先
* 结点分支判定
* 结点状态
*/
    vector<vector<int>> permute(vector<int>& nums) {
        vector<bool> used(nums.size(), false);
        dfs(nums, used);
        return res;
    }
private:
    vector<vector<int>> res;
    vector<int> path;
    // 使用系统的方法隐含的遍历搜索树
    void dfs(vector<int>& nums, vector<bool>& used) {
        if (path.size() == nums.size()) {
            res.push_back(path);
            return;
        }
        for (int i = 0; i < nums.size(); i++) {
            if (used[i] == true) continue;
            used[i] = true;
            path.push_back(nums[i]);
            dfs(nums, used);
            path.pop_back();
            used[i] = false;
        }
    }
};

标签:std,int,res,back,算法,vector,回溯,path,详解
From: https://blog.csdn.net/weixin_51332735/article/details/139300790

相关文章

  • 机器学习_回归算法详解
    机器学习中的回归算法用于预测连续数值输出(目标变量),通过学习输入特征(自变量)与目标变量之间的关系。以下详细介绍几种常见的回归算法及其工作原理,并提供相应的代码示例。1.线性回归(LinearRegression)1.1简介线性回归是最简单、最常用的回归算法之一,假设目标变量(y)......
  • python 卡尔曼滤波算法
    卡尔曼滤波(KalmanFilter)是一种有效的递归滤波器,用于线性动态系统的状态估计。它通过考虑先前的估计和当前的观测来提供下一个状态的最佳估计。卡尔曼滤波器广泛应用于导航系统、机器人定位、信号处理等领域。下面是一个简单的Python实现卡尔曼滤波算法的例子,用于估计一个一维......
  • 基于Matlab多算法去雾系统
    欢迎大家点赞、收藏、关注、评论啦,由于篇幅有限,只展示了部分核心代码。文章目录一项目简介二、功能三、系统四.总结一项目简介  一、项目背景与意义在图像处理和计算机视觉领域,图像去雾是一个重要的研究方向。由于雾天或其他恶劣天气条件,户外图像往往会出......
  • FPGA图像处理--CLAHE算法(一)
    FPGA交流群:838607138本文首发于公众号:FPGA开源工坊在介绍CLAHE算法之前必须要先提一下直方图均衡化,直方图均衡化算法是一种常见的图像增强算法,可以让像素的亮度分配的更加均匀从而获得一个比较好的观察效果。如下图就是经过直方图均衡化后的效果图。importcv2importnumpya......
  • 【计算机毕业设计】谷物识别系统Python+人工智能深度学习+TensorFlow+卷积算法网络模
    谷物识别系统,本系统使用Python作为主要编程语言,通过TensorFlow搭建ResNet50卷积神经算法网络模型,通过对11种谷物图片数据集('大米','小米','燕麦','玉米渣','红豆','绿豆','花生仁','荞麦','黄豆','黑米','黑豆')进行训练......
  • 操作系统之CPU调度算法——FCFS、SJF和SRTF
    目录前言 FCFS先来先服务调度算法定义与步骤 举例SJF短作业优先调度算法定义与步骤举例SRTF最短剩余时间优先调度算法定义与步骤举例结束语​​​​​​​前言 今天是坚持写博客的第12天,为不断坚持的自己和大家点赞。最近经历了一场时长半小时的答辩,还是需......
  • 零基础学Java第二十七天之前端-HTML5详解
    前端-HTML5详解一、概述HTML5是HTML的第五个版本,它对HTML进行了许多改进和扩展,使得网页开发更加丰富和便利。HTML5是Web标准的重要组成部分,旨在提高浏览器兼容性,统一网页开发标准。HTML5不仅包括了HTML的基本元素和标签,还新增了许多功能和API,为网页开发提供了更多的可能......
  • 算法随笔——数位DP
    学习链接https://www.luogu.com/article/tzeo544s数位DP标准模版:lldfs(intpos,intpre,intst,……,intlead,intlimit)//记搜{ if(pos>len)returnst;//剪枝 if((dp[pos][pre][st]……[……]!=-1&&(!limit)&&(!lead)))returndp[pos][pre][st]……[……];//记录当前值......
  • 算法随笔——状压DP题目整理
    枚举状态S的子集:for(ints=0;s<=tot;s++){ for(ints2=s;;s2=s&(s2-1)){枚举子集例题旅行商问题:P8733[蓝桥杯2020国C]补给在方格中填图案问题:蒙德里安问题国际象棋炮兵阵地......
  • 《计算机网络微课堂》实验5 交换机的自学习算法
    本实验的目的在于验证交换机的自学习算法。首先需要构建网络拓普,我们使用三台计算机,然后使用一个交换机把它们连接起来,我们选择自动连线将每个计算机连接到交换机上就可以了,那么交换机的接口是橙色的,我们切换右下角的实时和仿真模式,多切换几遍,直到交换机的接口变为绿色,接下来给各......