39.组合总和
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
题目思路:回溯算法
注意事项:1.无重复数组(使用start标记即可保证数组的不重复) 2.可以无限制重复被选取
3.后面的start应该是跟着i变化的
class Solution {
List<List<Integer>> res = new ArrayList<>();
LinkedList<Integer> temp = new LinkedList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
combinationSum1(candidates, target, 0, 0);
return res;
}
public void combinationSum1(int[] candidates, int target, int sum, int start){
if(sum >= target){
if(sum == target){
res.add(new ArrayList(temp));
}
return;
}
for(int i = start; i < candidates.length; i ++){
temp.push(candidates[i]);
sum += candidates[i];
combinationSum1(candidates, target, sum, i);
temp.pop();
sum -= candidates[i];
}
}
}
40.组合总和2
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明: 所有数字(包括目标数)都是正整数。 解集不能包含重复的组合。
思路:每个数只能使用一次——start不能取到i;不能包含重复组合——需要进行去重操作
去除重复操作的方法:1.对于数组进行排序,同时维护一个used数组。2.使用start进行记录。(十分巧妙,每次都可以取前面的1个,不需要使用额外标记)
进行一些细节修改,自己要明白都是哪些细节,为什么要修改。
class Solution {
List<List<Integer>> res = new ArrayList<>();
LinkedList<Integer> temp = new LinkedList<>();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
combinationSum1(candidates, target, 0, 0);
return res;
}
public void combinationSum1(int[] candidates, int target, int sum, int start){
if(sum == target){
res.add(new ArrayList(temp));
return;
}
for(int i = start; i < candidates.length && sum + candidates[i] <= target; i ++){
if(i > start && candidates[i] == candidates[i - 1])
continue;
temp.push(candidates[i]);
sum += candidates[i];
combinationSum1(candidates, target, sum, i + 1);
temp.pop();
sum -= candidates[i];
}
}
}
131.分割回文串
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例: 输入: “aab” 输出: [ [“aa”,“b”], [“a”,“a”,“b”] ]
存在一些问题目前还没有理清楚,难道不是选择两个位置就可以了吗?需要使用回溯算法吗?
另外,string的API整理一下。
注意事项:要求的是每一个子串都是回文串。
class Solution {
List<List<String>> lists = new ArrayList<>();
Deque<String> deque = new LinkedList<>();
public List<List<String>> partition(String s) {
backTracking(s, 0);
return lists;
}
private void backTracking(String s, int startIndex) {
if (startIndex >= s.length()) {
lists.add(new ArrayList(deque));
return;
}
for (int i = startIndex; i < s.length(); i++) {
if (isPalindrome(s, startIndex, i)) {
String str = s.substring(startIndex, i + 1);
deque.addLast(str);
} else {
continue;
}
backTracking(s, i + 1);
deque.removeLast();
}
}
public boolean isPalindrome(String s, int start, int end){
int left = start;
int right = end;
while(left <= right){
if(s.charAt(left) != s.charAt(right)){
return false;
}
left++;
right--;
}
return true;
}
}