【刷题篇】回溯算法(四)

文章目录

1、组合

给定两个整数 n 和 k,返回范围 1, n 中所有可能的 k 个数的组合。

你可以按 任何顺序 返回答案。

cpp 复制代码
class Solution {
public:
    vector<vector<int>> ret;
    int n,k;
    vector<int> path;
    vector<vector<int>> combine(int _n, int _k) {
        n=_n;
        k=_k;
        dfs(1);
        return ret;
        
    }
    void dfs(int begin)
    {
        if(path.size()==k)
        {
            ret.push_back(path);
            return ;
        }
        for(int i=begin;i<=n;i++)
        {
            path.push_back(i);
            dfs(i+1);
            path.pop_back();//恢复现场
        }     
    }
};

2、目标和

给你一个非负整数数组 nums 和一个整数 target 。

向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 :

例如,nums = 2, 1 ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1" 。

返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。

cpp 复制代码
class Solution {
public:
    int aim;
    int ret=0;
    int findTargetSumWays(vector<int>& nums, int target) {
        aim=target;
        dfs(nums,0,0);
        return ret;   
    }
    void dfs(vector<int> &nums,int pos,int target)
    {
        if(pos==nums.size())
        {
            if(target==aim) ret++;
            return ;
        }
        
        dfs(nums,pos+1,target+nums[pos]);

        dfs(nums,pos+1,target-nums[pos]);
    }
};

3、组合总和

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

cpp 复制代码
class Solution {
public:
    vector<vector<int>> ret;
    vector<int> path;
    //int sum;
    int target;
    vector<vector<int>> combinationSum(vector<int>& candidates, int _target) {
        target=_target;
        dfs(candidates,0,0);
        return ret;
    }

    void dfs(vector<int>& candidates,int begin,int sum)
    {
        if(sum==target)
        {
            ret.push_back(path);
            return ;
        }
        else if(sum>target)
            return ;
        //方法一
        // for(int i=begin;i<candidates.size();i++)
        // {
        //     path.push_back(candidates[i]);
        //     //sum+=candidates[i];
        //     dfs(candidates,i,sum+candidates[i]);
        //     path.pop_back();
        //     //sum-=candidates[i];
        // }
        //方法二
        for(int k=0;k*candidates[begin]+sum<=target;k++)
        {
            if(k) path.push_back(candidates[begin]);
            dfs(candidates,begin+1,sum+k*candidates[begin]);
        }

        for(int k=1;k*candidates[begin]+sum<=target;k++)
        {
            path.pop_back();
        }
    }
};

4、字母大小写全排列

给定一个字符串 s ,通过将字符串 s 中的每个字母转变大小写,我们可以获得一个新的字符串。

返回 所有可能得到的字符串集合 。以 任意顺序 返回输出。

cpp 复制代码
class Solution {
public:
    string path;
    vector<string> ret;
    int n;

    char change(char ch)
    {
        if(ch>='a'&&ch<='z') ch-=32;
        else ch+=32;
        return ch;  
    }
    
    vector<string> letterCasePermutation(string s) {
        n=s.size();
        dfs(s,0);
        return ret;
    }
    void dfs(string &s,int pos)
    {
        if(pos==n)
        {
            ret.push_back(path);
            return ;
        }
        char ch=s[pos];
        //不改变
        path.push_back(s[pos]);
        dfs(s,pos+1);
        path.pop_back();

        if(ch<'0'||ch>'9')
        {
            char tmp=change(ch);
            path.push_back(tmp);
            dfs(s,pos+1);
            path.pop_back();
        }
    }
};

5、优美的排列

假设有从 1 到 n 的 n 个整数。用这些整数构造一个数组 perm(下标从 1 开始),只要满足下述条件 之一 ,该数组就是一个 优美的排列 :

permi 能够被 i 整除

i 能够被 permi 整除

给你一个整数 n ,返回可以构造的 优美排列 的 数量 。

cpp 复制代码
class Solution {
public:
    bool check[16];
    int sum=0;
    int countArrangement(int n) {
        dfs(n,1);
        return sum;
    }

    void dfs(int n,int pos)
    {
        if(n+1==pos)
        {
            sum++;
            return ;
        }
        for(int i=1;i<=n;i++)
        {
            if(pos%i==0||i%pos==0)
            {
                if(check[i]==false)
                {
                    check[i]=true;
                    dfs(n,pos+1);
                    check[i]=false;
                }
            }
        }
    }
};
相关推荐
江畔柳前堤35 分钟前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore2 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考3 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX4 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面5 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号5 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽5 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI5 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者7 小时前
征程6工具链模型X86推理方式说明
算法
地平线开发者7 小时前
【征程6】校准量化中HistogramObserver解析
算法