当前位置: 首页 > wzjs >正文

呼和浩特重大消息宁波seo运营推广平台排名

呼和浩特重大消息,宁波seo运营推广平台排名,保定住房和城乡建设局网站,阜新建设工程信息网站回溯 什莫事回溯 回溯法也可以叫做回溯搜索法,它是一种搜索的方式 回溯的本质是穷举,穷举所有可能,然后选出我们想要的答案,如果想让回溯法高效一些,可以加一些剪枝的操作,但也改不了回溯法就是穷举的本…

回溯

什莫事回溯

回溯法也可以叫做回溯搜索法,它是一种搜索的方式

回溯的本质是穷举,穷举所有可能,然后选出我们想要的答案,如果想让回溯法高效一些,可以加一些剪枝的操作,但也改不了回溯法就是穷举的本质

回溯法并不高效为什么还要用它呢?
因为没得选,一些问题能暴力搜出来就不错了,撑死了再剪枝一下,还没有更高效的解法

回溯法,一般可以解决如下几种问题:

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

试错与回退
回溯法从解空间树的根节点出发,按深度优先策略逐层探索。若当前路径不满足约束条件或无法达到目标,则回退到上一状态(撤销最后一步选择),继续尝试其他分支

剪枝优化
在搜索过程中,通过预判当前路径的有效性,提前终止无效分支的探索(例如检测到冲突时),避免不必要的计算

递归算法!

  1. 确定递归函数的参数和返回值:
  2. 确定终止条件:
  3. 确定单层递归的逻辑:

回溯算法!

/*
vector<vector<int>> result;  // 存储所有解
vector<int> path;            // 当前路径
*/void backtracking(参数) {if (终止条件) {存放结果;                   //result.push_back(path);return;}for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {处理节点;                   // if (剪枝条件) continue; // 跳过无效分支// path.push_back(选择);   // 记录选择backtracking(路径,选择列表); // 递归回溯,撤销处理结果             // path.pop_back(); }
}

组合

77. 组合 - 力扣(LeetCode)

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

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

直接的算法是for循环 ,遍历每个位数可以选择的数😒
当k=2时 ,用两个for循环

for(int i=0;i<=n;i++){
for(int y=i+1;y<=n;y++) //因为是组合不是排列,不用在选出现过的数cout<<i<< " "<<y<<endl; 
}

如果n为100,k为50呢,如何写那么多for循环呢,while …?
虽然想暴力搜索,但是用for循环嵌套好像写不出来🤔

要解决 n为100,k为50的情况,暴力写法需要嵌套50层for循环,
那么回溯法就用递归来解决嵌套层数的问题

递归来做层叠嵌套(可以理解是开k层for循环),每一次的递归中嵌套一个for循环,那么递归就可以用于解决多层嵌套循环的问题了

由于回溯法解决的问题都可以抽象为树形结构(N叉树),用树形结构来理解回溯就容易多了🙂
![[Pasted image 20250414204405.png]]

图中可以发现n相当于树的宽度,k相当于树的深度
图中每次搜索到了叶子节点,我们就找到了一个结果
相当于只需要把达到叶子节点的结果收集起来,就可以求得 n个数中k个数的组合集合。

剪枝优化
如果for循环选择的起始位置之后的元素个数 已经不足 我们需要的元素个数了,那么就没有必要搜索了,如图4不用了

优化之后的for循环是:

for (int i = startIndex; i <= n - (k - path.size()-1); i++) // i为本次搜索的起始位置
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 - (k - path.size()) + 1; i++) { // 优化的地方path.push_back(i); // 处理节点backtracking(n, k, i + 1);path.pop_back(); // 回溯,撤销处理的节点}}
public:vector<vector<int>> combine(int n, int k) {backtracking(n, k, 1);return result;}
};

组合总和III

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

  • 只使用数字1到9
  • 每个数字 最多使用一次
    返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
    216. 组合总和 III - 力扣(LeetCode)

😍

class Solution {
public:vector<vector<int>> result;vector<int> path;int sum=0;void backtracking(int n, int k, int startIndex) {if (path.size() == k&&sum==n) {result.push_back(path);return;}for (int i = startIndex; i <= 9 ; i++) {path.push_back(i);sum+=i;backtracking(n, k, i + 1);sum-=i;path.pop_back();}}vector<vector<int>> combinationSum3(int k, int n) {backtracking( n,  k, 1);return result;}
};

剪枝优化 😕

其实这里sum这个参数也可以省略,每次targetSum (n)减去选取的元素数值,然后判断是否targetSum为0了

for循环选择的起始位置之后的元素个数 已经不足 我们需要的元素个数了,那么就没有必要搜索了

for (int i = startIndex; i <= n - (k - path.size()-1); i++) // i为本次搜索的起始位置

已选元素总和如果已经大于n(图中数值为4)了,那么往后遍历就没有意义了

if (sum > n) { // 剪枝操作return;
}

确定终止条件
k其实就已经限制树的深度,因为就取k个元素,树再往下深了没有意义。
所以如果path.size() 和 k相等了,就终止

优化结果🆗

class Solution {
private:vector<vector<int>> result; vector<int> path; void backtracking(int targetSum, int k, int sum, int startIndex) {if (sum > targetSum) { // 剪枝操作return; }if (path.size() == k) {if (sum == targetSum) result.push_back(path);return; }for (int i = startIndex; i <= 9 - (k - path.size()) + 1; i++) { // 剪枝sum += i; path.push_back(i); backtracking(targetSum, k, sum, i + 1); sum -= i; path.pop_back(); }}public:vector<vector<int>> combinationSum3(int k, int n) {backtracking(n, k, 0, 1);return result;}
};

电话号码的字母组合

17. 电话号码的字母组合 - 力扣(LeetCode)
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

确定回溯函数参数

  • 字符串s来收集叶子节点的结果
  • k是记录遍历第几个数字

确定终止条件

  • 遍历第几个数字等于 输入的数字个数
  • 或已存入数字个数等于 输入的数字个数

确定单层遍历逻辑

  • for循环
    本题每一个数字代表的是不同集合,也就是求不同集合之间的组合,
    而77. 组合 (opens new window)和216.组合总和III (opens new window)都是求同一个集合中的组合!
class Solution {
public:
const string letterMap[10] = {"", // 0"", // 1"abc", // 2"def", // 3"ghi", // 4"jkl", // 5"mno", // 6"pqrs", // 7"tuv", // 8"wxyz", // 9
};vector<string> result;string path;int sum=0;void backtracking(string digits, int k) {if (path.size() ==digits.size()) {result.push_back(path);return;}int digit = digits[k] - '0';        string letters = letterMap[digit];for(auto t:letterMap[digit]){path.push_back(t);backtracking(digits, k+1);path.pop_back();}}vector<string> letterCombinations(string digits) {if (digits.size() == 0) {return result;}backtracking(digits, 0);return result;}
};
http://www.dtcms.com/wzjs/138189.html

相关文章:

  • 金科科技 做网站电脑课程培训零基础
  • 深圳做网站排名哪家好网站页面的优化
  • 闲鱼怎么做钓鱼网站企业网站seo方案
  • 湖北武汉网站建设演艺搜索引擎查询
  • 初学者拟建网站朋友圈广告30元 1000次
  • 企业网站建设可行性网络整合营销理论
  • 山东旗舰建设集团网站海南网站网络推广
  • 顺德网站建seo关键词优化软件
  • 东莞企石做网站百度关键词搜索排名统计
  • 一台电脑如何做网站免费浏览网站推广
  • 网站建设单选题做百度推广的公司电话号码
  • 大连网站建设信息武汉seo关键词排名优化
  • 个人网站可以做哪些主题网盘资源免费观看
  • 做地铁建设的公司网站杭州seo软件
  • 鄂尔多斯网站制作公司我要登录百度
  • 云服务器和网站备案吗seo标题优化关键词怎么选
  • 长沙 网站设计 公司抖音seo什么意思
  • 做微信小程序网站国内做网站的公司
  • 网站价格全网营销推广公司
  • 网站title标签内容怎么设置南京seo网站管理
  • 吉林省人民政府门户网站首页关键词排名
  • 适合写论文的中小企业名录佛山抖音seo
  • 怎么做扫二维码登陆网站今天的新闻发布会
  • 深圳网站制作易捷网络2023年6月疫情情况
  • 知名网站建设公司社交媒体推广
  • 黔东南州两学一做教育网站怎么让自己上百度
  • 域名网站平台关键词竞价排名是什么意思
  • 建设生鲜网站价格建设网站制作公司
  • 网站建设uuiopseo优化师是什么
  • html好看的网站博客网站注册