代码随想录算法训练营第二十五天 | 216.组合总和III,17.电话号码的字母组合
1.代码随想录算法训练营第一天 | 数组理论基础,704. 二分查找,27. 移除元素2.代码随想录算法训练营第二天 | 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II3.代码随想录算法训练营第三天 | 链表理论基础,203.移除链表元素,707.设计链表,206.反转链表4.代码随想录算法训练营第四天 | 24. 两两交换链表中的节点,19.删除链表的倒数第N个节点,面试题 02.07. 链表相交,142.环形链表II5.代码随想录算法训练营第五天 | 复习和总结6.代码随想录算法训练营第六天|哈希表理论基础,242.有效的字母异位词,349. 两个数组的交集,202. 快乐数,1.两数之和7.代码随想录算法训练营第七天|454.四数相加II,383. 赎金信,15. 三数之和,18. 四数之和8.代码随想录算法训练营第八天 | 344.反转字符串,541.反转字符串II,卡码网:54.替换数字,151.翻转字符串里的单词,卡码网:55.右旋转字符串9.代码随想录算法训练营第十天 | 栈与队列理论基础,232.用栈实现队列,225.用队列实现栈10.代码随想录算法训练营第十一天|20. 有效的括号,1047. 删除字符串中的所有相邻重复项,150. 逆波兰表达式求值11.代码随想录算法训练营第十三天 | 239. 滑动窗口最大值,347.前 K 个高频元素12.代码随想录算法训练营第十四天 | 二叉树理论基础,递归遍历,分别迭代遍历, 统一迭代遍历13.代码随想录算法训练营第十五天 | 层序遍历 ,226.翻转二叉树,101.对称二叉树14.代码随想录算法训练营第十六天 |104.二叉树的最大深度,559.n叉树的最大深度,111.二叉树的最小深度,222.完全二叉树的节点个数15.代码随想录算法训练营第十八天 | 513.找树左下角的值,112. 路径总和,113.路径总和ii,106.从中序与后序遍历序列构造二叉树,105.从前序与中序遍历序列构造二叉树16.代码随想录算法训练营第二十天|654.最大二叉树,617.合并二叉树,700.二叉搜索树中的搜索,98.验证二叉搜索树17.代码随想录算法训练营第二十一天|530.二叉搜索树的最小绝对差,501.二叉搜索树中的众数,236. 二叉树的最近公共祖先18.代码随想录算法训练营第二十二天 | 235. 二叉搜索树的最近公共祖先,701.二叉搜索树中的插入操作,450.删除二叉搜索树中的节点19.代码随想录算法训练营第二十三天 | 669. 修剪二叉搜索树,108.将有 序数组转换为二叉搜索树,538.把二叉搜索树转换为累加树20.代码随想录算法训练营第二十四天 | 回溯算法理论基础,77. 组合
21.代码随想录算法训练营第二十五天 | 216.组合总和III,17.电话号码的字母组合
22.代码随想录算法训练营第二十七天 | 39. 组合总和,40.组合总和II,131.分割回文串一、216.组合总和III
题目链接:
学习前:
思路:
- 返回类型和参数:
void fun(int n, int k, int start)
- 终止条件:
int len = list.size();
if(len==k){
if(n==0 ){
List<Integer> temp = new ArrayList<>();
for (int i = 0; i < len; i++) temp.add(list.get(i));
res.add(temp);
}
return;
}
- 单次遍历内容
for (int i = start; i <= 9; i++) {
list.add(i);
n-=i;
fun(n,k,i+1);
n+=i;
list.remove(len);
}
进一步优化:
首先修改单次遍历中i的范围:
for (int i = start; i <= 10-k+len; i++) {
if(n-i<0) return;
if(n-i>0 && len==k-1) continue;
list.add(i);
n-=i;
fun(n,k,i+1);
n+=i;
list.remove(len);
}
故而终止条件修改为:
int len = list.size();
if(len==k){
List<Integer> temp = new ArrayList<>();
for (int i = 0; i < len; i++) temp.add(list.get(i));
res.add(temp);
return;
}
学习后:
加深理解
二、17.电话号码的字母组合
题目链接:
学习前:
思路:
- 定义成员变量:res存放结果集,list存放单个结果
private List<String> res;
private List<Character> list;
- 返回类型和参数:
void fun(String digits, int index)
- 终止条件:当输入字符串遍历完成后结束
int len = list.size();
if (index == digits.length()) {
StringBuffer sb = new StringBuffer();
for (char c : list) sb.append(c);
res.add(sb.toString());
return;
}
- 单次遍历内容:start表示当前数字对应的第一个字符,len表示当前数字对应的字符的个数
int cur = digits.charAt(index)-'0';
int start=(cur-2)*3;
int len=3;
if(cur==8 || cur==9) start++;
if(cur==7 || cur==9) len++;
for (int i = 97+start; i <97+start+len; i++) {
list.add((char)i);
fun(digits,index+1);
list.remove(list.size()-1);
}
学习后:
进一步优化:
首先用数组存放数字对应的字符集合
String[] numLetters={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
定义的成员变量:res存放结果集,per存放单个字符串
private List<String> res;
private StringBuffer per;
故而终止条件修改为:
if (index == digits.length()) {
res.add(per.toString());
return;
}
单次遍历内容修改为:
String s= numLetters[digits.charAt(index)-'0'];
for (int i = 0; i <s.length(); i++) {
per.append(s.charAt(i));
fun(digits,index+1,numLetters);
per.deleteCharAt(per.length()-1);
}
三、学习总结
- 时间:2h
- 继续了解回溯
合集:
算法刷题
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端