最近刷leetcode,在做到backtracking题目的时候总会有一些疑惑,其实对于backtracking题目都是很类似,代码也是有一定的模板的,这里总结一下:
一般的模板:
第一题:Subsets
(题目)Given a set of distinct integers, nums, return all possible subsets.
Note: The solution set must not contain duplicate subsets.
For example,
If nums = [1,2,3], a solution is:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
代码:这其实就是最简单的backtracking的代码结构
public class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res=new ArrayList<List<Integer>>();
res.add(new ArrayList<Integer>());
if(nums.length<=0){
return res;
}
Arrays.sort(nums);
List<Integer> tmp=new ArrayList<Integer>();
dfs(0,nums,tmp, res);
return res;
}
public void dfs(int start,int[] nums,List<Integer> tmp, List<List<Integer>> res){
for(int i=start;i<nums.length;i++){
tmp.add(nums[i]);
res.add(new ArrayList<Integer>(tmp));
dfs(i+1,nums,tmp,res);
tmp.remove(tmp.size()-1);
}
}
}
第二题:Subsets2
Given a collection of integers that might contain duplicates, nums, return all possible subsets.
Note: The solution set must not contain duplicate subsets.
For example,
If nums = [1,2,2], a solution is:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]
代码:
public class Solution {
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> res=new ArrayList<List<Integer>>();
List<Integer> tmp=new ArrayList<>();
if(nums.length<=0) return res;
Arrays.sort(nums);
dfs(0,nums,tmp,res);
return res;
}
void dfs(int start, int[] nums,List<Integer> tmp, List<List<Integer>> res){
res.add(new ArrayList<>(tmp));
for(int i=start;i<nums.length;i++){
if(i!=start&&nums[i]==nums[i-1])continue;
tmp.add(nums[i]);
dfs(i+1,nums,tmp,res);
tmp.remove(tmp.size()-1);
}
}
}
第三题:Combination
Given two integers n and k, return all possible combinations of k numbers out of 1 … n.
For example,
If n = 4 and k = 2, a solution is:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
代码:
public class Solution {
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> res=new ArrayList<List<Integer>>();
List<Integer> tmp=new ArrayList<Integer>();
if(k<=0||n<=0 ||k>n) return res;
dfs(1,k,n,tmp,res);
return res;
}
void dfs(int start,int k,int n,List<Integer> tmp,List<List<Integer>> res){
if(tmp.size()==k){
res.add(new ArrayList<>(tmp));
return;
}else{
for(int i=start;i<=n;i++){
tmp.add(i);
dfs(i+1,k,n,tmp,res);
tmp.remove(tmp.size()-1);
}
}
}
}
第四题:Combination Sum
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
The same repeated number may be chosen from C unlimited number of times.
Note:
All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.
For example, given candidate set [2, 3, 6, 7] and target 7,
A solution set is:
[
[7],
[2, 2, 3]
]
代码:
public class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> res=new ArrayList<List<Integer>>();
List<Integer> tmp=new ArrayList<Integer>();
//Arrays.sort(candidates);
if(target<0)return res;
if(candidates==null || candidates.length==0) return res;
dfs(0,target,candidates,tmp,res);
return res;
}
void dfs(int start,int target,int[] candidates, List<Integer> tmp, List<List<Integer>> res){
if(target<0) return;
if(target==0){
res.add(new ArrayList<Integer>(tmp));
}else{
for(int i=start;i<candidates.length;i++){
if(candidates[i]>target)continue;//通过此方法优化
tmp.add(candidates[i]);
dfs(i,target-candidates[i],candidates,tmp,res);
tmp.remove(tmp.size()-1);
}
}
}
}
第五题:Combination Sum II
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
Each number in C may only be used once in the combination.
Note:
All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.
For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8,
A solution set is:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
public class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> res=new ArrayList<List<Integer>>();
List<Integer> tmp=new ArrayList<>();
if(candidates==null || candidates.length==0)return res;
Arrays.sort(candidates);
dfs(0,target,candidates,tmp,res);
return res;
}
void dfs(int start,int target,int[] candidates,List<Integer> tmp,List<List<Integer>> res){
if(target<0) return;
if(target==0) {
res.add(new ArrayList<Integer>(tmp));
}else{
for(int i=start;i<candidates.length;i++){
if(i!=start&&candidates[i]==candidates[i-1])continue;
if(candidates[i]>target)continue;
tmp.add(candidates[i]);
dfs(i+1,target-candidates[i],candidates,tmp,res);
tmp.remove(tmp.size()-1);
}
}
}
}
第六题:Combination Sum III
题目:ind all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.
Example 1:
Input: k = 3, n = 7
Output:
[[1,2,4]]
Example 2:
Input: k = 3, n = 9
Output:
[[1,2,6], [1,3,5], [2,3,4]]
public class Solution {
public List<List<Integer>> combinationSum3(int k, int n) {
List<List<Integer>> res=new ArrayList<List<Integer>>();
List<Integer> tmp=new ArrayList<>();
if(k<=0 || n<1)return res;
dfs(1,k,n,tmp,res);
return res;
}
void dfs(int start,int k, int n, List<Integer> tmp,List<List<Integer>> res){
if(k<0 || n<0)return;
if(k==0&& n==0){
res.add(new ArrayList<Integer>(tmp));
}else{
for(int i=start;i<10;i++){
tmp.add(i);
dfs(i+1,k-1,n-i,tmp,res);
tmp.remove(tmp.size()-1);
}
}
}
}
第七题:Permutations
题目:
Given a collection of distinct numbers, return all possible permutations.
For example,
[1,2,3] have the following permutations:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
代码:
public class Solution {
boolean[] isValid;
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res=new ArrayList<List<Integer>>();
List<Integer> tmp=new ArrayList<Integer>();
isValid=new boolean[nums.length];
if(nums==null ||nums.length<=0)return res;
dfs(nums,tmp,res);
return res;
}
void dfs(int[] nums,List<Integer> tmp,List<List<Integer>> res){
if(tmp.size()==nums.length){
res.add(new ArrayList<Integer>(tmp));
}else{
for(int i=0;i<nums.length;i++){
if(!isValid[i]){
tmp.add(nums[i]);
isValid[i]=true;
dfs(nums,tmp,res);
tmp.remove(tmp.size()-1);
isValid[i]=false;
}
}
}
}
}
第八题:Permutations II
Given a collection of numbers that might contain duplicates, return all possible unique permutations.
For example,
[1,1,2] have the following unique permutations:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
public class Solution {
boolean[] isValid;
public List<List<Integer>> permuteUnique(int[] nums) {
/* Set<List<Integer>> res=new HashSet<List<Integer>>();
List<Integer> tmp=new ArrayList<Integer>();
isValid=new boolean[nums.length];
if(nums==null || nums.length==0)return new ArrayList<List<Integer>>(res);
dfs(nums,tmp,res);
return new ArrayList<List<Integer>>(res);
}
void dfs(int[] nums,List<Integer> tmp,Set<List<Integer>> res){
if(tmp.size()==nums.length){
res.add(new ArrayList<>(tmp));
}else{
for(int i=0;i<nums.length;i++){
if(!isValid[i]){
tmp.add(nums[i]);
isValid[i]=true;
dfs(nums,tmp,res);
tmp.remove(tmp.size()-1);
isValid[i]=false;
}
}
}
}*/
List<List<Integer>> res=new ArrayList<List<Integer>>();
List<Integer> tmp=new ArrayList<Integer>();
isValid=new boolean[nums.length];
Arrays.sort(nums);
if(nums==null || nums.length==0)return res;
dfs(nums,tmp,res);
return res;
}
void dfs(int[] nums,List<Integer> tmp,List<List<Integer>> res){
if(tmp.size()==nums.length){
res.add(new ArrayList<>(tmp));
}else{
for(int i=0;i<nums.length;i++){
if(i>0 && nums[i]==nums[i-1] && !isValid[i-1])continue;
if(!isValid[i]){
tmp.add(nums[i]);
isValid[i]=true;
dfs(nums,tmp,res);
isValid[i]=false;
tmp.remove(tmp.size()-1);
}
}
}
}
}