题目:
- 组合总和
40.组合总和II
131.分割回文串
学习内容:
39. 组合总和
class Solution {
List<Integer> path = new ArrayList<>();
List<List<Integer>> result = new ArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
backtracking(candidates, target, 0, 0);
return result;
}
// 1. 确定递归函数和参数
public void backtracking(int[] candidates, int target, int sum, int startIndex) {
// 2. 确定终止条件
if (sum == target) {
result.add(new ArrayList<>(path));
return;
}
if (sum > target) {
return;
}
// 3. 确定单层搜索的逻辑
for (int i = startIndex; i < candidates.length; i++) {
sum += candidates[i];
path.add(candidates[i]);
backtracking(candidates, target, sum, i);
sum -= candidates[i];
path.removeLast();
}
}
}
40.组合总和II
这道题非常难,其实模板都是一样的,难点在于去重的过程。这里的去重,是要去重树层而不是树枝!因为树枝无需去重,本来集合candidates就可能有n个值相同的元素,用多少个也不能算重复。 但是,在树层(横向)是需要去重的,如果前面一个数和自己值相同,同时不是第一个数字,那就必须执行去重了。
注意:与前面题目不同的是,要保持相同值的元素相邻,因此必须排序。
class Solution {
List<Integer> path = new ArrayList<>();
List<List<Integer>> result = new ArrayList<>();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
backtracking(candidates, target, 0, 0);
return result;
}
public void backtracking(int[] candidates, int target, int sum, int startIndex) {
if (sum == target) {
result.add(new ArrayList<>(path));
return;
}
if (sum > target) {
return;
}
for (int i = startIndex; i < candidates.length; i++) {
if (i > startIndex && candidates[i] == candidates[i - 1]) {
continue;
}
sum += candidates[i];
path.add(candidates[i]);
backtracking(candidates, target, sum, i + 1);
sum -= candidates[i];
path.removeLast();
}
}
}
131.分割回文串
这道题还是一个伪装成分割的组合问题,实际上还是那三步。
class Solution {
List<String> path = new ArrayList<>();
List<List<String>> result = new ArrayList<>();
public List<List<String>> partition(String s) {
backtracking(s, 0);
return result;
}
public void backtracking(String s, int startIndex) {
if (startIndex == s.length()) {
result.add(new ArrayList<>(path));
return;
}
for (int i = startIndex; i < s.length(); i++) {
String subString = s.substring(startIndex, i + 1);
if (isPalindrome(subString)) {
path.add(subString);
} else {
continue;
}
backtracking(s, i + 1);
path.removeLast();
}
}
public boolean isPalindrome(String s) {
int i = 0, j = s.length() - 1;
while (i < j) {
if (s.charAt(i) != s.charAt(j)) {
return false;
}
i++;
j--;
}
return true;
}
}
学习时间:
2024.4.2