代码随想录打卡Day22

今天开始正式刷回溯算法的题目了,由于之前学二叉树的时候已经提前接触过回溯的相关思想,所以听起来不是很费劲,今天的题目除了第一题看了视频讲解,其余两道题都是自己写出来的,用时还击败了100%的人,开心😊

77. 组合

这道题主要用来熟悉回溯算法的套路,回溯算法三部曲:1.确定输入参数和返回值(一般都是void);2.确定终止条件3.确定单层递归逻辑。
我感觉这个和之前二叉树的递归写法套路很像啊。回溯函数返回值为void,这就说明一般是需要定义全局变量来辅助操作的,回溯函数中就负责对这些全局变量进行操作。
这道题主要是一个排列组合问题,数学原理上没什么难的,重头戏在于剪枝,减去一些不必要的遍历情况。

class Solution {
public:
    vector<int> path;
    vector<vector<int>> result;
    vector<vector<int>> combine(int n, int k) {
        BackTracking(n, k, 1);
        return result;
    }
    void BackTracking(int n, int k, int Start_Index){
        //确定终止条件
        if(path.size() == k){
            result.push_back(path);
            return ;
        }
        //单层递归逻辑
        for(int i = Start_Index; i <= n - (k - path.size()) + 1; i++){
            path.push_back(i);
            BackTracking(n, k, i + 1);
            path.pop_back();
        }
    }
};

216.组合总和III

这道题和上一道题很像,区别在于组合里的树只能是1-9,且一个组合中的数字不能重复出现,组合中的数字之和必须等于目标值。那么这道题需要定义一个全局变量sum来记录当前数组中存储的元素之和,在遍历时,只需要判断当前的值是否小于等于n - sum,如果满足则进入循环体,否则直接退出循环(这就是一种剪枝的思路),在终止条件的判断上,不仅数组中的元素个数要满足要求,sum也必须恰好等于n才能将数组存入。

class Solution {
public:
    vector<int> path;
    vector<vector<int>> result;
    int sum = 0;
    vector<vector<int>> combinationSum3(int k, int n) {
        BackTracking(k, n, 1);
        return result;
    }
    void BackTracking(int k, int n, int Start_Index){
        //确认终止条件
        if(path.size() == k && sum == n){
            result.push_back(path);
            return ;
        }
        //单层递归逻辑
        for(int i = Start_Index; i <= n - sum && i <= 9; i++){
            path.push_back(i);
            sum += i;
            BackTracking(k, n, i + 1);
            sum -= i;
            path.pop_back();
        }
    }
};

17.电话号码的字母组合

这道题本来是想看视频的,但是任务布置说先自己想想,然后想着想着就做出来了(●ˇ∀ˇ●),这道题需要建立一个哈希表,主要用map<char, vector>来实现,其中键为字符’2’ - ‘9’,值为对应的字符向量,里面存放数字字符对应的所有可能的字母,这道题需要用二重循环来实现,外层循环负责遍历数字字符串,内层循环负责将数字转化成字母,递归和回溯的逻辑写在内层循环中。

class Solution {
public:
    vector<string> result;
    string path;
    map<char, vector<char>> My_Map = {
        {'2', {'a', 'b', 'c'}}, {'3', {'d', 'e', 'f'}}, {'4', {'g', 'h', 'i'}},
        {'5', {'j', 'k', 'l'}}, {'6', {'m', 'n', 'o'}}, {'7', {'p', 'q', 'r', 's'}},
        {'8', {'t', 'u', 'v'}}, {'9', {'w', 'x', 'y', 'z'}}
    };
    vector<string> letterCombinations(string digits) {
        BackTracking(digits, 0);
        return result;
    }
    void BackTracking(string s, int Start_Index){
        //确定终止条件
        if(s.size() == 0) return ;  //空字符串直接返回
        if(path.size() == s.size()){
            result.push_back(path);
            return ;
        }
        //单层递归逻辑
        for(int i = Start_Index; i < s.size(); i++){  //外层循环遍历数字字符串的所有字符
            for(int j = 0; j < My_Map[s[i]].size(); j++){ 
                //内层循环遍历某个数字对应的所有可能的字母
                path += My_Map[s[i]][j];
                BackTracking(s, i + 1);
                path.resize(path.size() - 1);
            }
        }
    }
};

nice!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值