(Leetcode)backtracking回溯法 题目汇总

回溯法 Backtracking

Backtracking比较形象来说可以用走迷宫做例子,大多人类一般就是使用回溯法,当走到一条死路,就往回退到前一个岔路,尝试另外一条,直到走出。

简介
中文称做「回溯法」,穷举多维度数据的方法,可以想作是多维度的「穷举搜索」(Exhaustive Search)。
大意是:把多维度数据看做是是一个多维向量(solution vector),然后运用递回依序递回穷举各个维度的值,制作出所有可能的数据(solution space),并且在递回途中避免列举出不正确的数据。

多维数据搜索示意图

特点
Backtracking的好处,是在递回过程中,能有效的避免列举出不正确的数据,省下很多时间。
另外还可以调整维度的顺序、每个维度中列举值的顺序。如果安排得宜,可以更快的找到数据。

Leetcode 回溯法题目汇总

Tip:只汇总了博主做过的且想的起来的题,可能会继续更新。。

39. 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]
]

Java Code

public class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> combination = new ArrayList<List<Integer>>();
        List<Integer> singleCombination = new ArrayList<Integer>();
        Arrays.sort(candidates);
        backtrackingCombination(combination, singleCombination, candidates, target, 0);

        return combination;
    }


    void backtrackingCombination(List<List<Integer>> combination, List<Integer> singleCombination, int[] candidates, int target, int start){
        if(target>0){
            for (int i = start; i <candidates.length && candidates[i]<=target; i++) {
                singleCombination.add(candidates[i]);
                backtrackingCombination(combination, singleCombination, candidates, target-candidates[i], i);
                singleCombination.remove(singleCombination.size()-1);           
            }

        }

        else if(target==0){
             combination.add(new ArrayList<Integer>(singleCombination));
        }
    }
}
40. 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]
]

Java Code

public class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> combination = new ArrayList<List<Integer>>();
        List<Integer> singleCombination = new ArrayList<Integer>();
        Arrays.sort(candidates);
        backtrackingCombination(combination, singleCombination, candidates, target, 0);

        return combination;
    }


    void backtrackingCombination(List<List<Integer>> combination, List<Integer> singleCombination, int[] candidates, int target, int start){
        if(target>0){
            for (int i = start; i <candidates.length && candidates[i]<=target; i++) {
                if( i>start && candidates[i]==candidates[i-1] )
                    continue;
                singleCombination.add(candidates[i]);
                backtrackingCombination(combination, singleCombination, candidates, target-candidates[i], i+1);
                singleCombination.remove(singleCombination.size()-1);           
            }

        }

        else if(target==0){
             combination.add(new ArrayList<Integer>(singleCombination));
        }
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] candidates = {10, 1, 2, 7, 6, 1, 5};
        int target = 8;
        List<List<Integer>> combination = new Solution().combinationSum2(candidates, target);
        for (int i = 0; i < combination.size(); i++) {
            for (int j = 0; j < combination.get(i).size(); j++) {
                System.out.print(combination.get(i).get(j)+" ");
            }
            System.out.println();
        }
    }

}
77. Combinations
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],
]

Java Code

public class Solution {
    public List<List<Integer>> combine(int n, int k) {
        ArrayList<List<Integer>> combination = new ArrayList<List<Integer>>();
        ArrayList<Integer> templist = new ArrayList<Integer>();
        backtracking(combination, templist, 1, k, n);
        return combination;
    }

    void backtracking(List<List<Integer>> combination, List<Integer> templist, int start, int k, int n){
        if(templist.size()>k) return;
        if(templist.size()==k){
            combination.add(new ArrayList<Integer>(templist));
        }
        for(int i=start; i<=n; i++){
            templist.add(i);
            backtracking(combination,templist,i+1,k,n);
            templist.remove(templist.size()-1);
        }
    }
}
78. 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],
  []
]

Java Code

public List<List<Integer>> subsets(int[] nums) {
    List<List<Integer>> list = new ArrayList<>();
    Arrays.sort(nums);
    backtrack(list, new ArrayList<>(), nums, 0);
    return list;
}

private void backtrack(List<List<Integer>> list , List<Integer> tempList, int [] nums, int start){
    list.add(new ArrayList<>(tempList));
    for(int i = start; i < nums.length; i++){
        tempList.add(nums[i]);
        backtrack(list, tempList, nums, i + 1);
        tempList.remove(tempList.size() - 1);
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值