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

文章目录

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 开始),只要满足下述条件 之一 ,该数组就是一个 优美的排列 :

perm[i] 能够被 i 整除

i 能够被 perm[i] 整除

给你一个整数 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;
                }
            }
        }
    }
};
相关推荐
88号技师6 小时前
2024年12月一区SCI-加权平均优化算法Weighted average algorithm-附Matlab免费代码
人工智能·算法·matlab·优化算法
IT猿手6 小时前
多目标应用(一):多目标麋鹿优化算法(MOEHO)求解10个工程应用,提供完整MATLAB代码
开发语言·人工智能·算法·机器学习·matlab
88号技师6 小时前
几款性能优秀的差分进化算法DE(SaDE、JADE,SHADE,LSHADE、LSHADE_SPACMA、LSHADE_EpSin)-附Matlab免费代码
开发语言·人工智能·算法·matlab·优化算法
我要学编程(ಥ_ಥ)7 小时前
一文详解“二叉树中的深搜“在算法中的应用
java·数据结构·算法·leetcode·深度优先
埃菲尔铁塔_CV算法7 小时前
FTT变换Matlab代码解释及应用场景
算法
许野平7 小时前
Rust: enum 和 i32 的区别和互换
python·算法·rust·enum·i32
chenziang18 小时前
leetcode hot100 合并区间
算法
chenziang18 小时前
leetcode hot100 对称二叉树
算法·leetcode·职场和发展
szuzhan.gy8 小时前
DS查找—二叉树平衡因子
数据结构·c++·算法
一只码代码的章鱼9 小时前
排序算法 (插入,选择,冒泡,希尔,快速,归并,堆排序)
数据结构·算法·排序算法