回溯算法 解题思路

2023-10-30

算法介绍

回溯法(Back Tracking Method)(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为 “回溯点”。

回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就 “回溯” 返回,尝试别的路径。

可以把回溯法看成是递归调用的一种特殊形式。

回溯法思路的简单描述是:把问题的解空间转化成了图或者树的结构表示,然后使用深度优先搜索策略进行遍历,遍历的过程中记录和寻找所有可行解或者最优解

回溯算法能解决的问题

  • 组合问题:N个数里面按一定规则找出k个数的集合
  • 排列问题:N个数按一定规则全排列,有几种排列方式
  • 切割问题:一个字符串按一定规则有几种切割方式
  • 子集问题:一个N个数的集合里有多少符合条件的子集
  • 棋盘问题:N皇后,解数独等等

解题模板

代码方面,回溯算法的框架:

result = []
def backtracking(路径, 选择列表):
	// 确定终止条件
    if 满足结束条件:
        result.add(路径)
        return
	
	// 单层搜索
    for 选择 in 选择列表:
        做选择
        backtracking(路径, 选择列表)
        撤销选择

核心就是 for 循环里面的递归,在递归调用之前「做选择」,在递归调用之后「撤销选择」。

总结就是:

循环 + 递归 = 回溯

1. 组合问题

在这里插入图片描述

class Solution {
private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& candidates, int target, int sum, int startIndex, vector<bool>& used) {
        if (sum == target) {
            result.push_back(path);
            return;
        }
        for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) {
            // used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
            // used[i - 1] == false,说明同一树层candidates[i - 1]使用过
            // 要对同一树层使用过的元素进行跳过
            if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false) {
                continue;
            }
            sum += candidates[i];
            path.push_back(candidates[i]);
            used[i] = true;
            backtracking(candidates, target, sum, i + 1, used); // 和39.组合总和的区别1,这里是i+1,每个数字在每个组合中只能使用一次
            used[i] = false;
            sum -= candidates[i];
            path.pop_back();
        }
    }

public:
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        vector<bool> used(candidates.size(), false);
        path.clear();
        result.clear();
        // 首先把给candidates排序,让其相同的元素都挨在一起。
        sort(candidates.begin(), candidates.end());
        backtracking(candidates, target, 0, 0, used);
        return result;
    }
};

这个组合问题中,最主要的问题是搞清楚 树层去重树枝去重
在这里插入图片描述

2. N皇后问题

在这里插入图片描述

class Solution {
public:
    // 存放不同解法
    vector<vector<string>> result;
    void backtracking(int n, int row, vector<string> chessboard) {
        if(row == n) {
            result.push_back(chessboard);
            return;
        }
        for(int colu = 0; colu < n; colu++) {
            if(IsValid(n, row, colu, chessboard)) {  // 验证合法就可以放
                chessboard[row][colu] = 'Q';  // 放置皇后
                backtracking(n, row + 1, chessboard);
                chessboard[row][colu] = '.';  // 回溯,撤销皇后
            }
        }
    }

    bool IsValid(int n, int row, int colu, vector<string> chessboard) {
        // 检查放到此处是否有效, 同列、对角是否有其他皇后(回溯时每行只取一次,所以不用检查同行)

        // 向上检查同列是否有皇后
        for(int i = 0; i < row; i++) {
            if(chessboard[i][colu] == 'Q') {
                return false;
            }
        }
        // 检查 135°(左上)是否有皇后
        for(int i = row-1, j = colu - 1; i >= 0 && j >= 0; i--, j--) {
            if(chessboard[i][j] == 'Q') {
                return false;
            }
        }
        // 检查 45°(右上)是否有皇后
        for(int i = row-1, j = colu + 1; i >= 0 && j < n; i--, j++) {
            if(chessboard[i][j] == 'Q') {
                return false;
            }
        }
        return true;
    }

    vector<vector<string>> solveNQueens(int n) {
        // 棋盘初始化
        vector<string> chessboard(n, string(n, '.'));
        // n:棋盘大小 0:从棋盘0行开始选
        backtracking(n, 0, chessboard);
        return result;
    }
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

回溯算法 解题思路 的相关文章

  • JVM垃圾回收器

    1 垃圾回收器的位置 2 垃圾回收器的基本概念 什么是垃圾回收器 JVM 为 Java 提供了垃圾回收机制 是一种偏自动的内存管理机制 简单来说 垃圾回收器会自动追踪所有正在使用的对象 并将其余未被使用的对象标记为垃圾 JVM会自动进行垃圾

随机推荐

  • 前端知识

    http www yyyweb com 5136 html 当经历所有大厂的实习后 小鱼 发布于 2018 08 15 分类 程序人生 阅读 43 评论 0 七月虽然不是一个丰收的季节 但却是一个十分酷热的月份 不知有多少小伙伴跟我一样 顶
  • MySQL server和workbench安装使用

    1 安装Notepad 运行下载的 npp 7 9 Installer x64 exe 2 安装MySQL 将mysql 8 0 22 winx64 zip解压缩 我将其放置D盘根目录下 进入文件夹 在目录中新建文件夹data和文件my i
  • docker登录私有镜像仓库时报错: x509: certificate signed by unknown authority

    文章目录 描述 报错 解决步骤 描述 由于机器在内网无法使用yum或rpm安装docker 所以使用的是离线安装 安装完成后 发现无法登录镜像地址 报错 Error response from daemon Get https swr cn
  • 队列的应用——(一)广度优先搜索

    在队列中 同样可以用于走迷宫 而且会出现一个与之前不同的情形 代码如下 C myqueue h include
  • OTA-apache本地服务器的搭建以及配置说明

    1 下载适配到本机型的Apache msi软件 这里我的电脑是32位的 下载的是apache 2 2 8 win32 x86 no ssl msi 2 apache环境变量的搭建 在计算机系统 gt 高级 gt 环境变量下的PATH后面添加
  • 一次注册表事故--无法打开exe文件

    下载了腾讯手游助手之后发现exe 的安装程序打不开 这就很郁闷了 下载了不同版本的都是打不开 难道是安装包有问题 为什么别人的电脑就能安装 我的电脑exe文件都能打开 为什么就腾讯手游助手不能打开呢 去网上搜集解决方法 百度经验上看到 说是
  • Cuda10.1总结1-概述

    概述 参考文献 官方在线文档 https docs nvidia com cuda archive 10 1 由于网页加载速度比较慢 可以参考如下文档 CUDA C Programming Guide C编程指南 CUDA C Best P
  • Android利用GridView制作横向列表

    p p p p p 1 在Activity对应的xml内 p p p pre class html pre
  • CSS重构

    1 重构和架构 重构是指在不改变代码行为的前提下 重写代码 使其更加简洁 易于复用 架构是指软件项目的各个不同部件之间的组合方式 优秀的架构 可预测 可以对软件的工作方式和结构做出准确的假设 可复用 在多处使用同一代码 无需重写 可扩展 比
  • 索引 第2关:用alter table创建索引

    任务描述 使用ALTER TABLE语句 1 为product商品表的descn商品详情的前两个字符和catid目录编号列添加索引descn catid 2 为product商品表的name商品名列添加唯一性索引unique name 3
  • qt自定义控件-多类别提示框

    一 前言 用惯了自带的messagebox 或者感觉效果不是很好看 或者有界面的特殊美观需求等等 那么就定制吧 1 单选项提示框 2 双选项提示框 3 滚动选项提示框 4 密码提示框 5 多组合选项提示框1 6 多组合选项提示框2 7 多组
  • 【华为OD机试真题2023 JS】快递投放问题

    华为OD机试真题 2023年度机试题库全覆盖 刷题指南点这里 快递投放问题 知识点图BFS搜索 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 有N个快递站点用字符串标识 某些站点之间有道路连接 每个站点有一些包裹要运输 每
  • java.lang.RuntimeException: com.intellij.ide.plugins.PluginManager

    描述 在mac电脑上的Android Studio 因为项目需求 加载plugins中的dart和Flutter插件 经过科学上网后 依然无法从AS中加载进来 曲折到Jetbrains官网下载了dart和Flutter的插件包 再引入到AS
  • PyCharm常用快捷键

    00 万能搜索 可以搜索文件名 类名 方法名 还可以搜索目录名 搜索目录的技巧是在在关键字前面加斜杠 Double Shift 01 代码智能提示 由于PyCharm默认的代码智能提示是 Ctrl Space 但是因为Ctrl Space是
  • LESS-23 LESS-25 LESS-25a

    LESS 23 源码 以此可知可以通过报错注入等方式 语法 mixed preg replace mixed pattern mixed replacement mixed subject int KaTeX parse error Exp
  • docker应用安装之部署Springboot项目

    docker部署springboot项目分为以下2步 springboot项目的JAR包生成镜像文件 将镜像文件生成容器 并完成部署 一 springboot项目的JAR包生成镜像文件 编写Dockerfile文件 执行以下命令 mkdir
  • 谷歌翻译插件Translate Web Pages

    官方下载页 https github com FilipePS Traduzir paginas web releases Chrome 谷歌浏览器 下载 TWP x x x Chromium zip Chrome安装扩展 配置 使用的操作
  • sqlcmd是个好玩意儿

    文章目录 sqlcmd是什么 sqlcmd命令 使用实例 使用sqlcmd创建数据 执行sql语句 sqlcmd是什么 sqlcmd真是开发者的福利 有了这玩意儿之后 数据库的部署 与数据库相关的一些自动化工作忽然简单了好多 也算是一个神器
  • 成绩分析(蓝桥杯)

    成绩分析 题目描述 小蓝给学生们组织了一场考试 卷面总分为 100 分 每个学生的得分都是一个 0 到 100 的整数 请计算这次考试的最高分 最低分和平均分 输入描述 输入的第一行包含一个整数 n 1 n 104 表示考试人数 接下来 n
  • 回溯算法 解题思路

    文章目录 算法介绍 回溯算法能解决的问题 解题模板 1 组合问题 2 N皇后问题 算法介绍 回溯法 Back Tracking Method 探索与回溯法 是一种选优搜索法 又称为试探法 按选优条件向前搜索 以达到目标 但当探索到某一步时