题目要求:给出一串数字,计算出其可能的字母组合方式。本题类似与剑指offer的青蛙跳台阶问题。
题目解析:
在所有的组合方式中,当前位字母的选择方式只有两种
- 自己单独转换成一个字母
- 和前面一位字母组合然后转换成一个字母(需要符合转换条件才行)
解题方法一:动态规划法
代码如下:
var translateNum = function (num) {
//将数字转为字符串
let str=String(num)
//定义dp数组
let dp=[]
//设置初始值
dp[0]=1
let number=Number(str[0]+str[1])
dp[1]=number>=10&&number<=25?2:1
//循环计算
for(let i=2;i<str.length;i++){
let num=Number(str[i-1]+str[i])
dp[i]=num>=10&&num<=25?dp[i-1]+dp[i-2]:dp[i-1]
}
return dp[str.length-1]
}
解题总结: 这道题是用的常规动态规划法,可以发现代码中的dp数组可以用三个变量循环滚动来代替,避免了内存浪费。下面就分析一下通过三个变量滚动来优化动态规划
解题方法二:优化版的动态规划
代码如下:
var translateNum = function (num) {
let str=String(num)
if(str.length==1){
return 1
}
//通过ppre,pre,methods来循环滚动而节约了一个数组的空间,同时也提高了运行速度
let ppre=1
let pre=1
let methods=0
for(let i=1;i<str.length;i++){
let num=Number(str[i-1]+str[i])
methods=num>=10&&num<=25?ppre+pre:pre
ppre=pre
pre=methods
}
return methods
};
总结 : 本题是青蛙跳台阶的升级版,加了一个限制条件。只要有这个动态规划将大问题分解成小问题的思路,本题也是相当简单的。如果没有这个思路,这道题是很难解开的。