leetcode算法题之递归--综合练习(一)

此专题对我们之前所学的关于递归的内容进行一个整合,大家可以自行练习,提升自己的编码能力。

本章目录

1.找出所有子集的异或总和在求和

找出所有子集的异或总和在求和

cpp 复制代码
class Solution {
    int ret =0;
    int path =0;
public:
    int subsetXORSum(vector<int>& nums) {
        dfs(nums,0);
        return ret;
    }
    void dfs(vector<int>& nums,int pos)
    {
        ret += path;
        for(int i=pos;i<nums.size();i++)
        {
            path ^= nums[i];
            dfs(nums,i+1);
            path ^= nums[i];//异或的消消乐原理
        }
    }
};

2.全排列II

全排列II

cpp 复制代码
class Solution {
    vector<vector<int>> ret;
    vector<int> path;
    bool check[9];
public:
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        dfs(nums,0);
        return ret;
    }
    // //法一:只关心不合法的,也就是不满足全排列要求的都剪枝掉
    // void dfs(vector<int>& nums,int pos)
    // {
    //     if(pos == nums.size())
    //     {
    //         ret.push_back(path);
    //         return;
    //     }
    //     for(int i=0;i<nums.size();i++)
    //     {
    //         if(check[i] == true||(i!=0&&nums[i] == nums[i-1]&&check[i-1] == false))
    //         {
    //             continue;
    //         }
    //         path.push_back(nums[i]);
    //         check[i] = true;
    //         dfs(nums,pos+1);
    //         path.pop_back();
    //         check[i] = false;
    //     }
    // }
    //法二:只关心合法的,也就是满足全排列要求的
    void dfs(vector<int>& nums,int pos)
    {
        if(pos == nums.size())
        {
            ret.push_back(path);
            return;
        }
        for(int i=0;i<nums.size();i++)
        {
            if(check[i] == false&&(i==0||nums[i]!=nums[i-1]||check[i-1] == true))
            {
                path.push_back(nums[i]);
                check[i] = true;
                dfs(nums,pos+1);
                path.pop_back();
                check[i] = false;
            }
        }
    }
};

3.电话号码的字母组合

电话号码的字母组合

cpp 复制代码
class Solution {
    string path;
    vector<string> ret;
    string hash[10] = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
public:
    vector<string> letterCombinations(string digits) {
        if(digits.size() == 0)
        {
            return ret;
        }
        dfs(digits,0);
        return ret;
    }
    void dfs(string& digits, int pos)
    {
        if(pos == digits.size())
        {
            ret.push_back(path);
            return;
        }
        for(auto ch:hash[digits[pos]-'0'])
        {
            path.push_back(ch);
            dfs(digits,pos+1);
            path.pop_back();
        }
    }
};

4.括号生成

括号生成

cpp 复制代码
class Solution {
    vector<string> ret;
    string path;
    int left,right,n;
public:
    //策略:左括号的数量等于右括号的数量
    //从头开始,左括号的数量大于等于右括号的数量
    vector<string> generateParenthesis(int _n) {
        n = _n;
        dfs();
        return ret;
    }
    void dfs()
    {
        if(right == n)
        {
            ret.push_back(path);
            return;
        }
        if(left<n)
        {
            path.push_back('(');
            left++;
            dfs();
            path.pop_back();
            left--;
        }
        if(left>right)
        {
            path.push_back(')');
            right++;
            dfs();
            path.pop_back();
            right--;
        }
    }
};

5.组合

组合

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

6.目标和

目标和

cpp 复制代码
class Solution {
    int ret;
    int aim;
    int n;
public:
    int findTargetSumWays(vector<int>& nums, int target) {
        aim = target;
        n = nums.size();
        dfs(nums,0,0);
        return ret;
    }
    void dfs(vector<int>& nums,int pos,int path)
    {
        //path做参数
        if(pos == nums.size())
        {
            if(path == aim) 
            {
                ret++;
            }
            return;
        }
        dfs(nums,pos+1,path+nums[pos]);
        dfs(nums,pos+1,path-nums[pos]);
    }
};
cpp 复制代码
class Solution {
    int ret;
    int aim;
    int path;
    int n;
public:
    int findTargetSumWays(vector<int>& nums, int target) {
        aim = target;
        n = nums.size();
        dfs(nums,0,0);
        return ret;
    }
    void dfs(vector<int>& nums,int pos,int path)
    {
        //path做全局变量
        if(pos == nums.size())
        {
            if(path == aim) 
            {
                ret++;
            }
            return;
        }
        path +=nums[pos];
        dfs(nums,pos+1,path);
        path -= nums[pos];

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

7.组合总和

组合总和

cpp 复制代码
class Solution {
    vector<vector<int>> ret;
    vector<int> path;
    int aim;
public:
    vector<vector<int>> combinationSum(vector<int>& c, int target) {
        aim = target;
        dfs(c,0,0);
        return ret;
    }
    void dfs(vector<int>& c,int pos,int sum)
    {
        if(sum>aim) return;
        if(sum == aim)
        {
            ret.push_back(path);
            return;
        }
        for(int i=pos;i<c.size();i++)
        {
            path.push_back(c[i]);
            dfs(c,i,sum+c[i]);
            path.pop_back();
        }
    }
};

8.字母大小写全排列

字母大小写全排列

cpp 复制代码
class Solution {
    vector<string> ret;
    string path;
public:
    vector<string> letterCasePermutation(string s) {
        dfs(s,0);
        return ret;
    }

    void dfs(string& s,int pos)
    {
        if(pos == s.size())
        {
            ret.push_back(path);
            return;
        }

        if(s[pos]<'0' || s[pos]>'9')
        {
            //变
            path.push_back(change(s[pos]));
            dfs(s,pos+1);
            path.pop_back();
        }
        //不变
        path.push_back(s[pos]);
        dfs(s,pos+1);
        path.pop_back();
    }
    char change(char ch)
    {
        if(ch>='a'&&ch<='z') ch -= 32;
        else ch += 32;
        return ch;
    }

};

9.优美的排列

优美的排列

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

    void dfs(int pos)
    {
        if(pos == n+1)
        {
            ret++;
            return;
        }
        for(int i=1;i<=n;i++)
        {
            if(!check[i] && (i%pos ==0 || pos%i == 0))
            {
                check[i] = true;
                dfs(pos+1);
                check[i] = false;
            }
        }
    }
};
相关推荐
钰爱&40 分钟前
【操作系统】Linux之线程同步二(头歌作业)
linux·运维·算法
拒绝头秃从我做起42 分钟前
14.最长公共前缀-力扣(LeetCode)
leetcode
Ws_44 分钟前
leetcode LCR 068 搜索插入位置
数据结构·python·算法·leetcode
灼华十一1 小时前
数据结构-布隆过滤器和可逆布隆过滤器
数据结构·算法·golang
adam_life2 小时前
OpenJudge_ 简单英文题_04:0/1 Knapsack
算法·动态规划
龙的爹23333 小时前
论文翻译 | The Capacity for Moral Self-Correction in Large Language Models
人工智能·深度学习·算法·机器学习·语言模型·自然语言处理·prompt
鸣弦artha4 小时前
蓝桥杯——杨辉三角
java·算法·蓝桥杯·eclipse
我是聪明的懒大王懒洋洋4 小时前
力扣力扣力:动态规划入门(1)
算法·leetcode·动态规划
丶Darling.4 小时前
Day44 | 动态规划 :状态机DP 买卖股票的最佳时机IV&&买卖股票的最佳时机III
算法·动态规划
TN_stark9325 小时前
多进程/线程并发服务器
服务器·算法·php