深度优先搜索DFS + 剪枝 | 回溯:力扣216. 组合总和 III

1、题目描述:

深度优先搜索DFS + 剪枝 | 回溯:力扣216. 组合总和 III_第1张图片

2、题解:

方法:深度优先搜索DFS + 剪枝 | 回溯

result = []
def backtrack(选择列表,路径):
    if 满足结束条件:
        result.add(路径)
        return
    for 选择 in 选择列表:
        做选择
        backtrack(选择列表,路径)
        撤销选择

# 做选择
将该选择从选择列表移除
路径.add(选择)

# 撤销选择
路径.remove(选择)
将该选择再加入选择列表

解决一个回溯问题,实际上就是一个决策树的遍历过程:
1、路径:也就是已经做出的选择。
2、选择列表:也就是你当前可以做的选择。
3、结束条件:也就是到达决策树底层,无法再做选择的条件。

每个组合不能有重复数字:backtrack(path,sum_+i,i+1)
剪枝:和大于n,或者路径长度大于k,剪枝
Python实现:

class Solution:
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        res = []
        def backtrack(path,sum_,start):
            if sum_ > n: #剪枝
                return
            if len(path) == k and sum_ == n:
                res.append(path[:])
                return 
            for i in range(start,10):
                if len(path) or sum_ + i > n: #剪枝
                    break
                path.append(i)		   #做选择
                backtrack(path,sum_+i,i+1) #向下选择
                path.pop()		   #撤销选择
        backtrack([],0,1)
        return res 

C++实现:

class Solution {
public:
    vector<vector<int>> combinationSum3(int k, int n) {
        //回溯
        vector<vector<int>> res;
        vector<int> path;
        int sum = 0,start = 1;
        backtrack(k,n,start,sum,path,res);
        return res;
    }
    void backtrack(int& k,int& n,int start,int sum,vector<int> path,vector<vector<int>>& res){
        if (sum > n){//剪枝
            return;
        }
        if  (path.size() == k && sum == n){
            res.push_back(path);
            return;
        }
        for (int i = start;i <= 9;i++ ){
            if (path.size() > k || sum + i > n){ //剪枝
                break;
            }
            path.push_back(i);			//做选择
            backtrack(k,n,i+1,sum+i,path,res);  //向下选择
            path.pop_back();			//撤销选择
        }
    }
};

3、复杂度分析:

在这里插入图片描述

你可能感兴趣的:(LeetCode高频面试题)