No.1
题目
组合总和
思路
- 回溯法
- 不限制数字使用次数,如何处理?
- 横向遍历树时,还需要使用
startIndex
,以避免对同一个组合重复多次搜索
- 但是在递归下一层时,参数中不需要
startIndex + 1
,表示允许从startIndex
开始搜索
- 数字集中出现
0
会怎么样?
- 考虑给空的
candidates
数组,怎么处理
递归分析
- 全局变量:
path
,result
- 返回值:空,参数:可用数字集,
target
,startIndex
- 终止条件
- 路径累计值和
target
相等,存储结果到result
,返回
- 路径累计值已经大于
target
,返回(剪枝)
路径走到尽头(耗尽所有可用数字),不存在,数字不限制使用次数
- 单层递归逻辑:
- 处理当前节点
- 递归进入下一层搜索
- 回溯,抛出当前节点
代码
| private List<Integer> path; |
| private List<List<Integer>> result; |
| |
| public void combineHelper(int[] candidates, int target, int startIndex) { |
| if (target == 0) { |
| result.add(new ArrayList<>(path)); |
| return; |
| } else if (target < 0) { |
| return; |
| } |
| |
| for (int i = startIndex; i < candidates.length; i++) { |
| path.add(candidates[i]); |
| target -= candidates[i]; |
| combineHelper(candidates, target, i); |
| target += candidates[i]; |
| path.remove(path.size() - 1); |
| } |
| } |
| |
| public List<List<Integer>> combinationSum(int[] candidates, int target) { |
| path = new ArrayList<>(); |
| result = new ArrayList<>(); |
| if (candidates.length == 0) |
| return result; |
| combineHelper(candidates, target, 0); |
| |
| return result; |
| } |
No.2
题目
组合总和 II
思路
- 回溯法,大体和No.1类似
- 这道题目和组合总和如下区别
- 本题数组
candidates
的元素是有重复的,而组合总和是无重复元素的数组candidates
- 新要求:解集不能包含重复的组合,怎么处理?
- 先对
candidates
排序,然后在横向遍历时,判断与path
末尾的数字是否相同,相同则continue
,跳过这个数字
递归分析
- 全局变量:
path
,result
- 返回值:空,参数:可用数字集,
target
,startIndex
- 终止条件
- 路径累计值和
target
相等,存储结果到result
,返回
- 路径累计值已经大于
target
,返回(剪枝)
- 路径走到尽头(耗尽所有可用数字),返回(剪枝)
- 单层递归逻辑:
- 处理当前节点
- 递归进入下一层搜索
- 回溯,抛出当前节点
代码
| private List<Integer> path; |
| private List<List<Integer>> result; |
| |
| public void combineHelper(int[] candidates, int target, int startIndex) { |
| if (target == 0) { |
| result.add(new ArrayList<>(path)); |
| return; |
| } else if (target < 0) { |
| return; |
| } |
| |
| if (target > 0 && startIndex >= candidates.length) |
| return; |
| |
| for (int i = startIndex; i < candidates.length; i++) { |
| int num = candidates[i]; |
| |
| if (i > startIndex && num == candidates[i - 1]) |
| continue; |
| path.add(num); |
| target -= num; |
| combineHelper(candidates, target, i + 1); |
| target += num; |
| path.remove(path.size() - 1); |
| } |
| } |
| |
| public List<List<Integer>> combinationSum2(int[] candidates, int target) { |
| path = new ArrayList<>(); |
| result = new ArrayList<>(); |
| if (candidates.length == 0) |
| return result; |
| |
| |
| Arrays.sort(candidates); |
| |
| combineHelper(candidates, target, 0); |
| return result; |
| } |
No.3
题目
分割回文串
思路
- 先写一个判断回文串的函数
- 回溯法
- 这是切割问题,类似组合问题
递归分析
- 全局变量:
path
,result
- 返回值:空,参数:原生字符串,
splitIndex
- 终止条件
- 字符串用光了,存储结果,返回
- 单层递归逻辑:
- 处理当前节点
- 割下来的字符串是回文串,进入下一层递归
- 回溯,抛出当前节点
代码
| public boolean judgeReversal(String s) { |
| int len = s.length(); |
| |
| for (int left = 0, right = len - 1;left <= right ; left++, right--) { |
| if (s.charAt(left) != s.charAt(right)) |
| return false; |
| } |
| |
| return true; |
| } |
| |
| private List<String> path; |
| private List<List<String>> result; |
| |
| public void partHelper(String s, int startIndex) { |
| if (startIndex >= s.length()) { |
| result.add(new ArrayList<>(path)); |
| return; |
| } |
| |
| for (int i = startIndex; i < s.length(); i++) { |
| String subStr = s.substring(startIndex, i + 1); |
| path.add(subStr); |
| if (judgeReversal(subStr)) |
| partHelper(s, i + 1); |
| path.remove(path.size() - 1); |
| } |
| } |
| |
| public List<List<String>> partition(String s) { |
| path = new ArrayList<>(); |
| result = new ArrayList<>(); |
| partHelper(s, 0); |
| |
| return result; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗