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

文章目录

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;
                }
            }
        }
    }
};
相关推荐
青椒大仙KI1112 分钟前
24/9/19 算法笔记 kaggle BankChurn数据分类
笔记·算法·分类
^^为欢几何^^16 分钟前
lodash中_.difference如何过滤数组
javascript·数据结构·算法
豆浩宇16 分钟前
Halcon OCR检测 免训练版
c++·人工智能·opencv·算法·计算机视觉·ocr
浅念同学32 分钟前
算法.图论-并查集上
java·算法·图论
何不遗憾呢41 分钟前
每日刷题(算法)
算法
立志成为coding大牛的菜鸟.1 小时前
力扣1143-最长公共子序列(Java详细题解)
java·算法·leetcode
鱼跃鹰飞1 小时前
Leetcode面试经典150题-130.被围绕的区域
java·算法·leetcode·面试·职场和发展·深度优先
liangbm31 小时前
数学建模笔记——动态规划
笔记·python·算法·数学建模·动态规划·背包问题·优化问题
潮汐退涨月冷风霜1 小时前
机器学习之非监督学习(四)K-means 聚类算法
学习·算法·机器学习
B站计算机毕业设计超人1 小时前
计算机毕业设计Python+Flask微博情感分析 微博舆情预测 微博爬虫 微博大数据 舆情分析系统 大数据毕业设计 NLP文本分类 机器学习 深度学习 AI
爬虫·python·深度学习·算法·机器学习·自然语言处理·数据可视化