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

做动图的网站知乎电子商务营销

做动图的网站知乎,电子商务营销,做淘宝导航网站,六安建设厅网站五一假期结束了,今天开始恢复正常打卡,今天我们将会接着上一次的回溯问题继续进行,今天我们主要是组合问题,我们在回溯算法的理论基础里面讲到过回溯算法可以解决的一类问题就是组合问题,那我们今天就重点来看看我们是…

        五一假期结束了,今天开始恢复正常打卡,今天我们将会接着上一次的回溯问题继续进行,今天我们主要是组合问题,我们在回溯算法的理论基础里面讲到过回溯算法可以解决的一类问题就是组合问题,那我们今天就重点来看看我们是如何运用回溯算法来解决组合问题的。

第一题对应力扣编号为39的题目组合总和

       这一道题目是组合总和,这个是不是与我们上一次的组合不一样了,其实我感觉应该是要求更多了,因为我们找到的组合还得要求满足和为题目给出的值,但是似乎我们没有数量限制了,我们来看一下具体的题目要求:

        看到题目我们先看一下有一个很重要的事情就是同一个元素是否允许使用多次,很明显这道题目是允许使用多次的,那我们就可以尝试使用回溯算法写出代码,还是遵循递归三部曲,但是大家注意这里我们还需要一个变量就是需要存储当前我取的元素的和,这个很重要这关系到我们的递归终止条件,因此我们递归与回溯相结合就可以写出代码:

class Solution {
private:vector<int> path;vector<vector<int>> result;//明确没一个变量的含义sum表示当前的和startIndex表示我可以递归的起点索引void backtracking(vector<int> &candidates, int target, int sum, int startIndex){if (sum > target) return;if (sum == target){result.push_back(path);return;}for (int i = startIndex; i < candidates.size(); ++i){sum += candidates[i];path.push_back(candidates[i]);//由于允许有重复所以还可以继续从i继续递归backtracking(candidates, target, sum, i);sum -= candidates[i];//回溯path.pop_back();}}
public:vector<vector<int>> combinationSum(vector<int>& candidates, int target) {result.clear();path.clear();backtracking(candidates, target, 0, 0);return result;}
};

        大家注意递归调用的参数,也就是那个startIndex参数我们要从i递归因为题目说了允许一个元素使用多次,后面的就不允许使用多次了,我们递归参数就需要改变了,我们每往一维数组里面添加一个元素我们就需要记录下此时的和,当我们回溯的时候我们记得要从和里减去当前元素就可以了,总体只要掌握了递归三部曲这道题目还是不难的。还有大家要注意我们递归本质是对一棵树进行操作,因此我们发现当前的和大于目标值的时候就直接return这种情况显然不是我们想要的。

第二题对应力扣编号为40的组合总和II

        我们来到了今天的第二题,这一道题就有难度了,其实难度在于去重,因为题目要求了不允许出现相同的组合,而且每一个元素只能使用一次,这个就有难度了,尤其是去重,我们先来看一下题目的要求:

       看到示例一有朋友可能就会有疑问,为啥会出现两个1,不是每一个元素只能使用一次吗?大家注意我们的原数组里存在两个值一样的元素,所以我们这里的两个1是两个元素,因此这是符合题目要求的,理解这里对我们理解后面的去重也很重要,我们后面的去重就要避免去掉这种情况,为了让大家理解,代码随想录上引入了树层与树枝两个概念,重点是对树层去重,树枝重点是避免同一个元素使用多次,我们看一下给出的示意图:

       注意理解示意图的逻辑,我们是一个树形结构,其实我们原先的for循环的过程就是构造树层的过程,我们的递归与回溯的过程就是构造树枝的过程,我们在树枝是允许出现值相等的元素的,因为我们最初集合里本就可能出现两个值一样的元素,但是大家注意我们树层就不允许一样了,因为一旦树层一样就会导致重复,我这次取出1去递归回溯,我可以找出【1,2】这个组合,如果我树层里还要取出1的话那么我们回溯递归还是会找到【1,2】这样的组合因此会出现重复,这个要注意去重,但是我们又要避免去掉示例1的情况,因此我们要对数组排序,并且第一个1是要使用的,否则就会去掉不应该去的情况,

       这个图比较难理解,注意蓝色字体的描述,我们是允许树枝上出现相同元素的,但树层不允许,我们可以写出如下代码:

class Solution {
private:vector<int> path;vector<vector<int>> result;void backtracking(vector<int> &candidates, int target, int sum, int startIndex, vector<bool> &used){//递归的终止条件if (sum > target) return;if (sum == target){result.push_back(path);return;}//单层递归的逻辑for (int i = startIndex; i < candidates.size(); ++i){//树层去重(注意题目要求不能出现重复的组合而且每一个元素只能出现一次如果两个元素相等的话其实是相同数值的元素可以出现多次)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);sum -= candidates[i];path.pop_back();used[i] = false;}}
public:vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {vector<bool> used(candidates.size(), false);result.clear();path.clear();sort(candidates.begin(), candidates.end());backtracking(candidates, target, 0, 0, used);return result;}
};

      重点理解这个去重操作,注意树层去重就可以了,这道题我就给大家解释到这里,我们接着下一道题目。

第三题对应力扣编号为131的题目分割回文串

       我们来到了最后一题,其实这道题大家仔细阅读思考就会发现这也是一道组合问题,

       这个组合找的是回文串的组合,因此我们应该先写出判断回文串的函数,然后再去递归回溯,但这里我们需要注意的是递归的终止条件应该如何写,还有一个就是判断回文串的函数,大家读完题目就可以发现这里很明显字符串的每一个元素都只能使用一次,我直接给出代码解释一下:

class Solution {
private:vector<string> path;vector<vector<string>> result;void backtracking(const string &s, int startIndex){//注意递归的终止条件是我当前的索引大于等于字符串的长度if (startIndex >= s.size()){result.push_back(path);return;}//单层递归的逻辑for (int i = startIndex; i < s.size(); ++i){//发现遍历到某一个位置是回文串说明我们就要把这一部分截取出来存放到我们的一维数组里面if (isPalindrome(s, startIndex, i)){string str = s.substr(startIndex, i - startIndex + 1);path.push_back(str);}else continue;backtracking(s, i + 1);//递归继续去找其他的符合要求的path.pop_back();//回溯将添加进去的字符串弹出来这样才可以确保我们可以找到所有的字符串}}//判断回文串的函数就是使用类似于双指针的思想逐一对比bool isPalindrome(const string &s, int start, int end){for (int i = start, j = end; i < j; i++, j--){if (s[i] != s[j]) return false;}return true;}
public:vector<vector<string>> partition(string s) {result.clear();path.clear();backtracking(s, 0);return result;}
};

      这是这道题目的完整代码,包括了判断回文字符串以及递归回溯的过程,模拟切割线,其实就是startIndex是上一层已经确定了的分割线,i是这一层试图寻找的新分割线这点要注意,这也是题目的难点,希望大家可以好好理解一下。

总结

       回溯算法其实是一种很有难度的算法,大家一定要多理解,其实通过这几道题目大家也可以发现我们存在一套模板,大家务必掌握好递归三部曲,意识到递归与回溯不分家就可以了,今天就先到这里,我们明天见!

http://www.dtcms.com/wzjs/284353.html

相关文章:

  • 广州网站建设一般多少钱百度搜索风云榜排名
  • 网站建设的时候如何上传图片网易企业邮箱
  • 许昌知名网站建设价格收录查询工具
  • 连云港做网站公司哪家好中国国家培训网
  • 深圳专业网站制作费用搜索引擎优化免费
  • 手机访问网站建设中seo系统培训哪家好
  • 有没有个人做网站的免费个人推广引流平台
  • html做网站的代码企业新网站seo推广
  • 查看WordPress网站插件百度站长工具综合查询
  • 做网站广告有哪些职位中国教师教育培训网
  • 惠州网站建设培训外贸网络推广公司
  • 石家庄做网站备案有哪些公司宁波的网络营销服务公司
  • 怎么做国外网站百度经验手机版官网
  • 自己的网站怎么做app吗百度seo关键词排名 s
  • 网站建设申请武汉seo工作室
  • 本地网站建设视频平台推广费用一般是多少
  • 天津市建设安全协会网站上海seo网站推广
  • 吉县网站建设百度app怎么找人工客服
  • 设计师导航网站广州seo排名外包
  • 昆明学校网站建设网站优化排名软件网站
  • 校园微网站界面如何做公司网站推广
  • 网站的二级栏目怎么做上海专业网络推广公司
  • 房地产网站策划建站官网
  • 小企业网站如何建设好bing搜索引擎入口
  • 学校网站建设企业线上推广方案怎么做
  • 安徽省铜陵市建设银行网站网站排名优化专业定制
  • bluehost空间内直接安装wordpress失败seo行业网
  • 高端网页开发宁波seo快速优化
  • 石家庄网站设计公司排名网站优化师
  • 制作企业网站的实训报告杭州百度开户