组合问题——LeetCode题目17:电话号码的字母组合
原题描述
+
给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例
输入:“23”
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]
说明:尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。
原题链接:https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number
思路解析
+
本质上此题等价于————给定若干个集合,从每个集合中挑选一个元素,求所有可能的组合情况。
我希望你能有一个刷题经验:凡是涉及到排列组合的题目,基本都可以通过递归解决。因为不管是排列还是组合,都是从先求子问题,然后再求原问题。递推和递归是数学和编程中非常重要的思想,多写多练才会有感觉。
回到题目,我们开始从最简单的情况开始分析。
1. 最原子问题——只有一个集合时
这是显而易见的,假设集合 ,那么直接返回即可。
2. 最简单的特殊情况——当给定两个集合时
假设集合 ,要让集合 中的每个元素和集合 中的每个元素两两相碰,因此返回的是 ,一个二重循环就能搞定。
3.从特殊到一般——当给定多个集合时
先假设只有三个集合 ,不跳步的做法是,先求 和 的组合情况,返回一个新的集合 ,然后再做 和 的组合情况即为所求。集合数量再增加之后,思路也是一样的。
所以我们总能把原问题逐步拆解成子问题来求解,这就是此题的递推关系。假设 表示从第 个集合到第 个集合的组合结果, 表示第 个集合,那么有如下递推关系:好了,现在你可以写代码了。虽然递归程序的时间复杂度并不是最优的,但递归程序确实能够显示出一个人对问题的理解深度,分而治之是算法中的常用策略,希望大家多多练习。
这道题你会了,那么请你思考另一个问题——全排列应该怎么求?
复杂度分析
+
- 时间复杂度:
- 空间复杂度:
C++参考代码
+
class Solution {
public:
vector<string> letterCombinations(string digits) {
vector<string> res;
map<char, string> table = {
{'2', "abc"}, {'3', "def"}, {'4', "ghi"},
{'5', "jkl"}, {'6', "mno"}, {'7', "pqrs"},
{'8', "tuv"}, {'9', "wxyz"}
};
if (!digits.size()) return res;
else if (digits.size() == 1) {
for (int i = 0; i < table[digits[0]].size(); ++i) {
string tmp(1, table[digits[0]][i]);
res.push_back(tmp);
}
return res;
}
vector<string> suffix = letterCombinations(digits.substr(1, digits.size() - 1));
for (int i = 0; i < table[digits[0]].size(); ++i) {
for (int j = 0; j < suffix.size(); ++j) {
string tmp = "";
tmp += table[digits[0]][i];
tmp += suffix[j];
res.push_back(tmp);
}
}
return res;
}
};
- 并行爬虫和数据清洗工具(开源)
- 响应式web布局中iframe的自适应
- 简单易学的机器学习算法——协同过滤推荐算法(2)
- 详解ROC/AUC计算过程
- 汉字数组排序及如何检测汉字
- 简单易学的机器学习算法——主成分分析(PCA)
- 基于Xgboost + LR + Keras 建模评估用户信用状态
- canvas实现拖动页面时显示窗口视频
- 鼠标滚轮事件介绍
- Understanding delete
- objC与js通信实现--WebViewJavascriptBridge
- 简单易学的机器学习算法——岭回归(Ridge Regression)
- QQ空间(日志、说说、个人信息)python爬虫源码(一天可抓取 400 万条数据)
- 文本分类实战: 机器学习vs深度学习算法对比(附代码)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- VBA解压缩ZIP文件08——解压-没有压缩
- 一文教你搞懂C语言的Q格式
- 基础算法之排序算法
- C++核心准则E4,5:设计并构建不变量
- Selenium实际应用注入并执行Javascript语句
- 什么是Python的 “内存管理机制”
- 2020年手工webpack构建react项目,完美支持ssr,包括css和图片资源
- php中赋值、浅拷贝与深拷贝
- 2020最新:100道有答案的前端面试题(下)
- UI自动化测试之ddt实战
- KVM 之网络配置
- Mysql操作
- CentOS7+nginx+uwsgi+Django部署之路
- 【翻译】200行代码讲透RUST FUTURES (4)
- 使用Flask部署图像分类模型