LeetCode——backtracking分析

最近刷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);
                }
            }
        }
     }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值