模板
private void backtrack("原始参数") {
//终止条件(递归必须要有终止条件)
if ("终止条件") {
//一些逻辑操作(可有可无,视情况而定)
return;
}
for (int i = "for循环开始的参数"; i < "for循环结束的参数"; i++) {
//一些逻辑操作(可有可无,视情况而定)
//做出选择
//递归
backtrack("新的参数");
//一些逻辑操作(可有可无,视情况而定)
//撤销选择
}
}
子集(可重复)
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> ans = new ArrayList<>();//存放结果
public List<List<Integer>> subsets(int[] nums) {
if(nums.length == 0){
return result;
}
backtrack(0, nums);
return result;
}
public void backtrack(int s, int[] nums){
result.add(new ArrayList<>(ans));
if(s >= nums.length){//终止条件
return;
}
for(int i = s; i < nums.length; i++){
ans.add(nums[i]);//做出选择
backtrack(i+1, nums);//递归
ans.remove(ans.size() - 1);//撤销
}
}
}
子集(不可重复)
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> ans = new ArrayList<>();
boolean[] used;
public List<List<Integer>> subsetsWithDup(int[] nums) {
if(nums.length == 0){
result.add(ans);
return result;
}
Arrays.sort(nums);
used = new boolean[nums.length];
backtrack(0, nums);
return result;
}
public void backtrack(int s, int[] nums){
result.add(new ArrayList<>(ans));
if(s >= nums.length){//终止条件
return;
}
for(int i = s; i < nums.length; i++){
if(i > 0 && nums[i] == nums[i - 1] && !used[i - 1]){//逻辑操作(判断前后数相同情况下,只使用其中一个)
continue;
}
ans.add(nums[i]);
used[i] = true;//使用标记
backtrack(i+1, nums);
ans.remove(ans.size() - 1);
used[i] = false;
}
}
}
全排列(不重复的全排列)
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> ans = new ArrayList<>();
boolean[] used;
public List<List<Integer>> permuteUnique(int[] nums) {
if(nums.length == 0){
result.add(ans);
return result;
}
Arrays.sort(nums);
used = new boolean[nums.length];
backTrack(nums);
return result;
}
public void backTrack(int[] nums){
if(ans.size() == nums.length){
result.add(new ArrayList<>(ans));
return;
}
for(int i = 0; i < nums.length; i++){
if(used[i]) continue;
if(i > 0 && nums[i] == nums[i - 1] && !used[i - 1]){
continue;
}
ans.add(nums[i]);
used[i] = true;
backTrack(nums);
ans.remove(ans.size() - 1);
used[i] = false;
}
}
}
组合总和(无重复数组元素)
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
Arrays.sort(candidates);
backtrack(0, target, 0, candidates);
return res;
}
public void backtrack(int u, int target, int sum, int[] candidates){
if(sum == target) {
res.add(new ArrayList<>(path));
return;
}
for(int i = u; i < candidates.length; i++) {
int rs = candidates[i] + sum;
if(rs <= target) {
path.add(candidates[i]);
backtrack(i, target, rs, candidates);
path.remove(path.size()-1);
} else {
break;
}
}
}
}
组合总数2(有重复元素)
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
backtrack(0, target, candidates);
return res;
}
public void backtrack(int u, int target, int[] candidates){
if(target < 0){
return;
}
if(target == 0){
res.add(new ArrayList<>(path));
return;
}
for(int i = u; i < candidates.length; i++){
if(candidates[i]<=target){
if(i>u && candidates[i] == candidates[i-1]){
continue;
}
path.add(candidates[i]);
backtrack(i+1, target-candidates[i], candidates);
path.remove(path.size() - 1);
}
}
}
}
以下内容属于本人刷题时的总结,不会的题目会在评论区和官方解析看答案,如有重复,会删除