前言:
如果你一点也不了解什么叫做回溯算法,那么推荐你看看这一篇回溯入门,让你快速了解回溯算法的基本原理及框架
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
来源:力扣(LeetCode)电话号码的字母组合
思路:
从示例来看,我们首先能想到的最直接的思路就是循环套循环来组合输出,但是循环会根据输入的数字越来越多导致套的层次越多,这时候我们就可以考虑学习上一篇的思路,使用递归回溯的办法解决。
vector arr{ "","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz" };//写两个空串是为了能用下标直接对应九宫格里的字母
下面我们来边写边解释:
class Solution {
public:vector arr{"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};vector _arr;//收集所有子集string tmp;//存储子集void BackTracking(string digits,int k)//k是记录遍历到第几个数字{if(tmp.size()==digits.size())//终止条件{_arr.push_back(tmp);//存放子集到总集合return;}//digits[k]-'0'是将数字字符改成数字//arr[digits[k]-'0']访问数字字符对应下标位置的字符串for(int i=0;itmp.push_back(arr[digits[k]-'0'][i]);//收集字符BackTracking(digits,k+1);//递归,k+1为下一次进入的字符串tmp.pop_back();//回溯,撤销节点}}vector letterCombinations(string digits) {if(digits.size()==0){return _arr;}BackTracking(digits,0);return _arr;}
};
给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target 的不同组合数少于 150 个。
来源:力扣(LeetCode)组合总和
思路:
本题的主要关键信息是:所有数字不相同且可以无限制使用,组合与组合不相同,提示中已经表明不会出现0,所以我们直接忽略0带来的结果。
我们将candidates为升序排列,
由于数字的数量不做限制,我们每次for循环开始的位置就可以是上次循环变量i所在的位置,而递归的深度限制就是总和达到target或者大于它的时候
下面我们边写边解释:
class Solution {
public:vector> arr;//收集符合条件子集vector _arr;//存放单个子集//sum为_arr子集的总和数 begin为循环开始位置void BackTracking(vector& candidates,int target,int sum,int begin){if(sum>target)//终止条件{return;}if(sum==target){arr.push_back(_arr);return;}for(int i=begin;isum+=candidates[i];//递加总和_arr.push_back(candidates[i]);//存放至子集BackTracking(candidates,target,sum,i);//i不加1 表示可以重复取该数sum-=candidates[i];//回溯,撤销上一次的运算_arr.pop_back();//回溯,撤销上一次的运算}}vector> combinationSum(vector& candidates, int target) {sort(candidates.begin(),candidates.end());//先排序,后续更好优化BackTracking(candidates,target,0,0);return arr;}
};
优化后的代码:
class Solution {
public:vector> arr;vector _arr;void BackTracking(vector& candidates,int target,int sum,int begin){if(sum==target){arr.push_back(_arr);return;}//如果sum+candidates[i]>target遍历可以停止了for(int i=begin;isum+=candidates[i];_arr.push_back(candidates[i]);BackTracking(candidates,target,sum,i);sum-=candidates[i];_arr.pop_back();}}vector> combinationSum(vector& candidates, int target) {sort(candidates.begin(),candidates.end());BackTracking(candidates,target,0,0);return arr;}
};
这个题相较与回溯入门中的两个组合总和题
主要区别是没有组合里元素数量限制和单个元素数量限制
上一篇:JetsonNano搭载的扩展板的OLED显示屏的使用(实时显示IP、内存、CPU等)
下一篇:桂林最新学区划分,最新或2023(历届)桂林最新中小学学区划分 2020桂林市区小学学区划分公布图 桂林最新最全小学学区划分