力扣刷题之-回溯算法笔记【摘自代码随想录】

void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

**

1.元素不重复,每个只能取一次

**
例题:leetcode 46.全排列
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

** 输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]**

class Solution {
public:
    // 路径:记录在 path 中
    // 选择列表:nums 中不存在于path 的那些元素(used[i] 为 false)
    // 结束条件:nums 中的元素全都在 path 中出现
    vector<vector<int>>res;
    vector<int>path;
    void backtrack(vector<int>& nums,vector<int> used){
        if(path.size()==nums.size()){//触发结束条件
            res.push_back(path);//收集结果
            return;//记得返回
        }
        //单层搜索
        for(int i=0;i<nums.size();i++){
         	// 排除不合法的选择
            if(used[i]==1)continue;// nums[i] 已经在 path 中,跳过
            // 做选择
            path.push_back(nums[i]);
            //记录nums[i]否用过
            used[i]=1;
            // 进入下一层决策树
            backtrack(nums,used);
            //回溯,取消选择撤销处理结果
            path.pop_back();
            used[i]=0;
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        vector<int>used(nums.size(),0);
        backtrack(nums,used);
        return res;
    }
};

2.元素不重复,可以无限制取

例题:leetcode 39.组合总和
给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

对于给定的输入,保证和为 target 的不同组合数少于 150 个。
输入:candidates = [2,3,6,7], target = 7
输出:[[2,2,3],[7]]

class Solution {
public:
    int sum=0;
    vector<vector<int>>ans;
    vector<int>path;
    //无重复元素数组,无限制重复取
    void backtrack(vector<int>& candidates, int target,int startindex){
        if(sum==target){
            ans.push_back(path);
            return ;
        }
        if(sum>target){
            return;
        }
        for(int i=startindex;i<candidates.size();i++){
            sum+=candidates[i];
            
            path.push_back(candidates[i]);
            backtrack(candidates,target,i);///从自身位置开始
            sum-=candidates[i];
            path.pop_back();
        }
    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
         backtrack(candidates,target,0);
         vector<bool>used(candidates.size());
         return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值