代码随想录训练营 Day27
今日任务
39.组合总和
40.组合总和Ⅱ
131.分割回文串
语言:Java
39. 组合总和
链接:https://leetcode.cn/problems/combination-sum/
优化:对candidates排序,再回溯,方便剪枝优化
class Solution {
List<List<Integer>> result;
List<Integer> path;
int curSum;
public void backTracking(int[] candidates, int startIdx, int target){
if(curSum >= target){
if(curSum == target){
result.add(new ArrayList(path));
}
return;
}
for(int i = startIdx; i < candidates.length; i++){
path.add(candidates[i]);
curSum += candidates[i];
backTracking(candidates, i, target);
curSum -= candidates[i];
path.remove(path.size() - 1);
}
}
public List<List<Integer>> combinationSum(int[] candidates, int target) {
result = new ArrayList<List<Integer>>();
path = new ArrayList<Integer>();
curSum = 0;
backTracking(candidates, 0, target);
return result;
}
}
40. 组合总和Ⅱ
链接:https://leetcode.cn/problems/combination-sum-ii/
解题关键:明确“去重”的逻辑是在哪一层发生的,它是在树的同一层中,如果已有相同元素使用过,那么该元素就不可以再用了。我们每次沿着树向下一层走的时候都会更新startIdx,所以只需要通过在startIdx后判断是否有重复的元素即可;同时还要注意去重需要对数组进行排序。
class Solution {
List<List<Integer>> result;
List<Integer> path;
int curSum;
int lastUsed;
public void backTracking(int[] candidates, int startIdx, int target){
if(curSum >= target){
if(curSum == target){
result.add(new ArrayList(path));
}
return;
}
for(int i = startIdx; i < candidates.length && curSum <= target; i++){
if(i > startIdx && candidates[i - 1] == candidates[i]){
continue;
}
path.add(candidates[i]);
curSum += candidates[i];
//Each number in candidates may only be used once in the combination.
backTracking(candidates, i + 1, target);
curSum -= candidates[i];
path.remove(path.size() - 1);
}
}
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
result = new ArrayList<List<Integer>>();
path = new ArrayList<Integer>();
curSum = 0;
lastUsed = 0;
Arrays.sort(candidates);
backTracking(candidates, 0, target);
return result;
}
}
131. 分割回文串
链接:https://leetcode.cn/problems/palindrome-partitioning/
解题关键:先判断回文串,保证是回文串的前提下才继续递归
class Solution {
List<List<String>> result;
List<String> path;
public void backTracking(String s, int startIdx){
if(startIdx >= s.length()){
result.add(new ArrayList(path));
return;
}
for(int i = startIdx; i < s.length(); i++){
String temp = s.substring(startIdx, i + 1);
if(!isPalindrome(startIdx, i, s)){
continue;
}
else{
path.add(temp);
backTracking(s, i + 1);
path.remove(path.size() - 1);
}
}
}
public boolean isPalindrome(int startIdx, int endIdx, String s){
while(startIdx < endIdx){
if(s.charAt(startIdx) != s.charAt(endIdx)){
return false;
}
startIdx++;
endIdx--;
}
return true;
}
public List<List<String>> partition(String s) {
result = new ArrayList<List<String>>();
path = new ArrayList<String>();
backTracking(s, 0);
return result;
}
}