剑指offer之将数字转为字符串

213 阅读1分钟

题目要求:给出一串数字,计算出其可能的字母组合方式。本题类似与剑指offer的青蛙跳台阶问题。

原题链接点这里

image.png

题目解析:

在所有的组合方式中,当前位字母的选择方式只有两种

  1. 自己单独转换成一个字母
  2. 和前面一位字母组合然后转换成一个字母(需要符合转换条件才行

解题方法一:动态规划法

代码如下:

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]
    }

image.png

解题总结: 这道题是用的常规动态规划法,可以发现代码中的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
};

image.png

总结 : 本题是青蛙跳台阶的升级版,加了一个限制条件。只要有这个动态规划将大问题分解成小问题的思路,本题也是相当简单的。如果没有这个思路,这道题是很难解开的。