代码随想录算法训练营第二十五天|216.组合总和III、17.电话号码的字母组合

LeetCode 216.组合总和III

链接:216. 组合总和 III

思路:

这道题目与77. 组合仅有一点不同,就是这道题目找到的组合的总和需要满足额外的条件。所以在递归终止条件里增加了一个条件就是当sum==n的时候才把答案push进最终结果里。除此之外,还有一点区别就是这里的n不再是作为搜索范围而存在的,而是以target而存在的,题目里提到了每一个数都可以从1到9里面选择,所以搜索范围就变成了i <=9,并且这里也用上了和之前一样的剪枝,即当从i开始到9结束的数组长度小于要求的数组长度k时,可以直接跳过循环。

代码:

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> path;
    vector<vector<int>> combinationSum3(int k, int n) {
        backtracking(k, n, 1, 0);
        return ans;
    }
    void backtracking(int k, int n, int idx, int sum)
    {
        if (k < 1)
        {
            if (sum == n)
                ans.push_back(path);
            return;
        }
        for (int i = idx; i <= 9 - (k-1); i++)
        {
            sum += i;
            path.push_back(i);
            backtracking(k-1, n, i+1, sum);
            sum -= i;
            path.pop_back();
        }
    }
};

LeetCode 17.电话号码的字母组合

链接:17. 电话号码的字母组合

思路:

这道题目本质上还是找字母的组合,只不过这里手动划分了每颗子树的搜索范围。我们可以根据电话号码的按键及对应的字母构建一个哈希表,然后根据输入的数字来获取相对应的字母的集合,该集合即为每颗子树的搜索范围。在for循环里,我们用chars代表了每个数字对应的字母的集合的长度,然后在该数字对应的字母的集合上进行搜索和回溯。

需要注意的是我们使用了numIdx来表示当前所在数字的位数,用来索引digits获取里面的由char表示的2~9之间的数字,然后通过减‘0’的方式把该数字转换成int类型,再用转换好的int类型取hashmap里索引该数字对应的字母表。

在节省空间方面其实可以用更加有效率的数组来做哈希表,因为实际上数字范围一共只有0~9,所以只需要一共大小为10的数组记录每个数字对应的字母即可。

    const string letterMap[10] = {
    "", // 0
    "", // 1
    "abc", // 2
    "def", // 3
    "ghi", // 4
    "jkl", // 5
    "mno", // 6
    "pqrs", // 7
    "tuv", // 8
    "wxyz", // 9
    };

代码:

class Solution {
public:
    unordered_map<int, vector<char>> hashmap
    {
        {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> ans;
    string temp;
    vector<string> letterCombinations(string digits) {
        backtracking(digits, 0);
        return ans;
    }
    void backtracking(string &digits, int numIdx)
    {
        if (numIdx > digits.size() - 1)
        {
            ans.push_back(temp);
            return;
        }
        // 获取当前数字所代表的字母串
        vector<char> chars = hashmap[digits[numIdx] - '0'];
        // 遍历字母串,把每次遍历的元素放入string
        for (int i = 0; i < chars.size(); i++)
        {
            temp.push_back(chars[i]);
            backtracking(digits, numIdx + 1);
            // 回溯
            temp.pop_back();
        }
        return;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值