LeetCode 17. Letter Combinations of a Phone Number【回溯】⭐⭐⭐⭐⭐

题目描述

在这里插入图片描述

知识点

回溯
在这里插入图片描述

实现

码前思考

  1. emmm,这难道要用暴力进行求解?感觉无论如何时间复杂度都是 O ( 3 N ∗ 4 ∗ M ) O(3^N*4*M) O(3N4M),其中 N + M = d i g i t s . s i z e ( ) N+M=digits.size() N+M=digits.size(),不可能再进行优化了。。。

代码实现

//感觉就是非常正常的字符串模拟题吧。。。也许是?
//再加上一点hash的思想
class Solution {
public:
    vector<string> letterCombinations(string digits) {
        //进行特判
        if(digits.size() == 0){
            return {};
        }

        //首先建立字符“2..9”到字母集合的映射
        map<char,vector<string> > mp;

        //可以像下面这样初始化vector!学到了
        mp['2'] = {"a","b","c"};
        mp['3'] = {"d","e","f"};
        mp['4'] = {"g","h","i"};
        mp['5'] = {"j","k","l"};
        mp['6'] = {"m","n","o"};
        mp['7'] = {"p","q","r","s"};
        mp['8'] = {"t","u","v"};
        mp['9'] = {"w","x","y","z"};

        //定义一个pre,一个after
        vector<string> pre;
        vector<string> after;

        //初始化pre
        for(string c : mp[digits[0]]){
            pre.push_back(c);
        }

        int size = digits.size();

        for(int i=1;i<size;i++){
            char digit = digits[i];
            for(string str : pre){
                for(string c : mp[digit]){
                    after.push_back(str+c);
                }
            }
            pre = after;
            after.clear();
        }

        return pre;
    }
};

码后反思

  1. 看见题解里面写用回溯(没有剪枝的回溯),感觉那样才是考点,我上面写的完全就是暴力枚举了,回溯更加专业一些~~代码如下:
//感觉就是非常正常的字符串模拟题吧。。。也许是?
//再加上一点hash的思想
class Solution {
private:
    //首先建立字符“2..9”到字母集合的映射
    map<char,string> mp;
    //结果
    vector<string> ans;
    //记录匹配情况的字符串
    string current;
public:
    vector<string> letterCombinations(string digits) {
        //进行特判
        if(digits.size() == 0){
            return {};
        }
        mp['2'] = "abc";
        mp['3'] = "def";
        mp['4'] = "ghi";
        mp['5'] = "jkl";
        mp['6'] = "mno";
        mp['7'] = "pqrs";
        mp['8'] = "tuv";
        mp['9'] = "wxyz";

        //从digits的第一位开始进行回溯,也就是对一棵树进行遍历
        dfs(0,digits);
        return ans;
    }

    //注意string最好是传地址更快些
    void dfs(int index,string& digits){
        if(index == digits.size()){
            ans.push_back(current);
        }

        for(char c : mp[digits[index]]){
            //压入尾元素
            current.push_back(c);
            dfs(index+1,digits);
            //删除尾元素
            current.pop_back();
        }
    }
};
  1. 上面的代码更加规范!用到了算法的回溯思想
    在这里插入图片描述
  2. 原来string类型也可以push_back()pop_back(),长知识了!

二刷代码

依然只会暴力求解。没有想到回溯的写法。。。
回溯主要在于这个回溯树的理解,如果你在解题的时候,脑子中有了一棵树,那么就可以使用回溯算法!回溯算法的核心就是DFS

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值