39. 组合总和
- 学习文章链接:
- 思路:在组合总和的基础上注意去重逻辑即可。这里也提了个醒,startIndex与 i 之间的关系。
- 代码:
class Solution {
List<List<Integer>> res = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
if (candidates == null || candidates.length == 0) return res;
backtracking(candidates, target, 0, 0);
return res;
}
public void backtracking(int[] candidates, int target, int sum, int startIndex) {
if (sum > target) return;
if (sum == target) {
res.add(new ArrayList<>(path));
return;
}
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
- 学习文章链接:
- 思路:
- 这题与39.组合总和十分相似,但是不同点在于数组中每个元素只能使用一次,因此递归时需要 i + 1,另外不同点是该题需要跳过同一树层已经使用过的元素,因此使用used数组来记录元素的使用情况。
- ( used[i - 1] == true,说明同一树枝candidates[i - 1]使用过 )
- ( used[i - 1] == false,说明同一层candidates[i - 1]使用过 )
- 代码:
class Solution {
List<List<Integer>> res = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
if (candidates.length == 0 || candidates == null) return res;
Arrays.sort(candidates);
boolean[] used = new boolean[candidates.length];
backtracking(candidates, target, 0, 0, used);
return res;
}
public void backtracking(int[] candidates, int target, int sum, int startIndex, boolean[] used){
if (sum > target) return;
if (sum == target) {
res.add(new ArrayList<>(path));
return;
}
for (int i = startIndex; i < candidates.length; i++) {
if (i > 0 && candidates[i - 1] == candidates[i] && used[i - 1] == false) continue;
sum += candidates[i];
used[i] = true;
path.add(candidates[i]);
backtracking(candidates, target, sum, i + 1, used);
sum -= candidates[i];
used[i] = false;
path.removeLast();
startIndex++;
}
}
}
131.分割回文串
- 学习文章链接:
- 思路:分割问题与组合问题类似,所以代码的框架类似。详情见如下代码块。
- 代码:
class Solution {
List<List<String>> res = new ArrayList<>();
LinkedList<String> path = new LinkedList<>();
public List<List<String>> partition(String s) {
if (s.length() == 0) return res;
backtracking(s, 0);
return res;
}
public void backtracking(String s, int index){
if (index == s.length()) {
res.add(new ArrayList<>(path));
return;
}
for (int i = index; i < s.length(); i++) {
if (isPoliRome(s, index, i)) {
String str = s.substring(index, i + 1);
path.add(str);
} else {
continue;
}
backtracking(s, i + 1);
path.removeLast();
}
}
public boolean isPoliRome(String str, int start, int end) {
for (int i = start, j = end; i < j; i++, j--) {
if (str.charAt(i) != str.charAt(j)) {
return false;
}
}
return true;
}
}