代码随想录算法训练营| 第77题. 组合, 216.组合总和III ,17.电话号码的字母组合
理论基础
- 回溯的本质是穷举
- 但是可以增加一些剪枝算法来进行优化
- 回溯法解决的问题都可以抽象为树形结构,集合的大小构成了树的宽度,递归的深度决定了树的深度
第77题. 组合
文章来源:https://programmercarl.com/0077.组合.html#算法公开课
题目链接:https://leetcode.cn/problems/combinations/description/
视频链接:https://www.bilibili.com/video/BV1ti4y1L7cv/?vd_source=6cb513d59bf1f73f86d4225e9803d47b
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
void backtracking(int n,int k,int startIndex){
//终止条件
if(path.size()==k){
res.push_back(path);
return;
}
//否则继续进行回溯遍历
for(int i=startIndex;i<=n;i++){
path.push_back(i);
//进行下一个元素的选择
backtracking(n,k,i+1);
path.pop_back(); //每push进入一个元素,回溯是就要将该元素再pop出去,以便能增加新的元素进去
}
}
vector<vector<int>> combine(int n, int k) {
backtracking(n,k,1);
return res;
}
};
216.组合总和III
文章链接:https://programmercarl.com/0216.组合总和III.html#算法公开课
题目链接:https://leetcode.cn/problems/combination-sum-iii/description/
- 此题与上一题相比,关键在于多了path总和的计算,因此可在backtracking中增加一个sum参数,用来记录每一次backtracking时sum的值是多少。
class Solution {
public:
vector<int> path;
vector<vector<int>> res;
void backtracking(int k,int n,int startIndex,int sum){
if(path.size()==k&&sum==n){
res.push_back(path);
return;
}
for(int i=startIndex;i<=9;i++){
if(i>n-sum) break; //剪枝
path.push_back(i);
backtracking(k,n,i+1,sum+i);
path.pop_back();
}
}
vector<vector<int>> combinationSum3(int k, int n) {
backtracking(k,n,1,0);
return res;
}
};
17.电话号码的字母组合
文章链接:https://programmercarl.com/0017.电话号码的字母组合.html#算法公开课
题目链接:https://leetcode.cn/problems/letter-combinations-of-a-phone-number/description/
一开始写的代码如下,会造成一些错误和不必要的运算
class Solution {
public:
string path;
vector<string> res;
int n=0,index=0;
unordered_map<char,vector<char>> map;
void init(string digits){
n=digits.size();
map['2']={'a','b','c'};
map['3']={'d','e','f'};
map['4']={'g','h','i'};
map['5']={'j','k','l'};
map['6']={'m','n','o'};
map['7']={'p','q','r','s'};
map['8']={'t','u','v'};
map['9']={'w','x','y','z'};
}
void backtracking(string digits,int index){
if(index==n){
res.push_back(path);
return;
}
for(char i:map[digits[index]]){
path.push_back(i);
backtracking(digits,index+1);
path.pop_back();
}
}
vector<string> letterCombinations(string digits) {
init(digits);
backtracking(digits,0);
return res;
}
};
修改后:
- 注意如果digits为空,则应该在主函数中加一句空情况
- 全局参数可以不用定义的过多,不然显得很冗余
- 将参数string digits改为const string& digits
class Solution {
public:
string path;
vector<string> res;
unordered_map<char,vector<char>> map;
void init(string digits){
map['2']={'a','b','c'};
map['3']={'d','e','f'};
map['4']={'g','h','i'};
map['5']={'j','k','l'};
map['6']={'m','n','o'};
map['7']={'p','q','r','s'};
map['8']={'t','u','v'};
map['9']={'w','x','y','z'};
}
void backtracking(const string& digits,int index){
if(index==digits.size()){
res.push_back(path);
return;
}
for(char chr:map[digits[index]]){
path.push_back(chr);
backtracking(digits,index+1);
path.pop_back();
}
}
vector<string> letterCombinations(string digits) {
if(digits.size()==0) return {};
init(digits);
backtracking(digits,0);
return res;
}
};
分类:
代码随想录算法训练营
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构