仅为个人记录复盘学习历程,解题思路来自代码随想录
代码随想录刷题笔记总结网址:
代码随想录
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明: 所有数字(包括目标数)都是正整数。解集不能包含重复的组合。
提供参数:整数数组candicates,目标数 target 。
关键思路:
这道题关键在于分辨是否能重复使用,
重复使用在题目中大概分为两种:
1.同一个元素是否能重复使用。
2.不同元素但值相同是否能重复使用。
本题在横向遍历上同一个元素显然不能重复使用,不同元素但值相同显然也不能重复使用,这样会带来重复结果。在纵向遍历上,同一个元素显然不能重复使用,但不同元素值相同可以重复使用,但在本题中横向与纵向使用的是相同的数据集合,所以我们要加入判断,来实现在横向遍历和纵向遍历上的差异,这个判断就需要构造used数组,在candicates[i]使用前,我们将used[i]设置为true,这样在递归向下遍历时我们就知道这是纵向遍历,重复数值不同元素可以使用,而回溯后将used[i]设置为false,这样我们就可以在横向遍历中判断出当前重复数字元素是回溯而来使用过的,进而跳过本次判断。
主要操作:
递归三要素
1.返回值类型和输入参数:
使用全局变量res接收所有结果,使用全局变量path接收单个结果,返回值类型为void;
在递归中需要参数参数candicates数组,目标值target,累加和sum,起始索引startIndex,used数组。
2.终止条件:
当sum>target,返回。(使用剪枝后可以不用)
当sum==target,将结果加入结果集,返回。
3.单层递归逻辑:
从起始索引位置开始回溯遍历解空间树,在每次回溯遍历前判断是否需要跳过本次循环(横向已经遍历过)。
代码大致如下:
//
public List>res;
public Listpath;
public List> combinationSum2(int[] candidates, int target) {
res=new ArrayList<>();
path=new ArrayList<>();
Listused=new ArrayList<>();
for(int i=0;i used){
//
if(sum==target){
res.add(new ArrayList(path));
return;
}
//
for(int i=startIndex;i0&&candidates[i]==candidates[i-1]&&used.get(i-1)==false)continue;
path.add(candidates[i]);
sum+=candidates[i];
used.set(i,true);
backTrace(candidates,target,sum,i+1,used);
used.set(i,false);
sum-=candidates[i];
path.remove(path.size()-1);
}
}
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例: 输入: "aab" 输出: [ ["aa","b"], ["a","a","b"] ]
回文串:从前往后,和从后往前是一样的,例如:“aba”是,“abab”不是。
提供参数:字符串s。
主要操作:
递归三要素
1.返回值类型和输入参数:
使用全局变量res接收所有结果,使用全局变量path接收单个结果,返回值类型为void;
需要输入参数字符串s,起始索引startIndex。
2.终止条件:
startIndex就是分割线的体现,当startIndex>=s.length()时,说明找到了一种符合条件的切割方式,因为在单层递归逻辑的for循环中进行了判断,如果不满足回文条件则跳过当次循环。
3.单层递归逻辑:
以startIndex为起始位置,for循环横向探索解空间树,回溯递归纵向探索解空间树,在for循环中递归向下遍历前进行判断,判断当次的切割子串是否满足回文串的条件,不满足则跳出当次循环,继续下一次横向遍历。
代码大致如下:
//
List>res;
Listpath;
public List> partition(String s) {
res=new ArrayList<>();
path=new ArrayList<>();
backTrace(s,0);
return res;
}
public void backTrace(String s,int startIndex){
//
if(startIndex>=s.length()){
res.add(new ArrayList(path));
return;
}
for(int i=startIndex;i