牛客网面试必刷TOP101-07动态规划BM69 把数字翻译成字符串

描述

有一种将字母编码成数字的方式:'a'->1, 'b->2', ... , 'z->26'。

现在给一串数字,返回有多少种可能的译码结果

数据范围:字符串长度满足 0

进阶:空间复杂度 O(n),时间复杂度 O(n)

示例1

输入:

"12"

返回值:

2

说明:

2种可能的译码结果(”ab” 或”l”)  

示例2

输入:

"31717126241541717"

返回值:

192

说明:

192种可能的译码结果  
一、问题分析

首先读题,仔细看描述中的内容,发现需求是

1.有一种将字母编码成数字的方式:'a'->1,'b'->2,...,'z'->26。

2.现在给一串数字,返回有多少种可能的译码结果。

3.数据范围:字符串长度满足n大于0小于等于90

4.进阶:空间复杂度O(n),时间复杂度O(n)

二、解题思路

1.思路:对于普通数组1-9,译码方式只有一种,但是对于11-19,21-26,译码方式有可选择的两种方案,因此我们使用动态规划将两种方案累计。

2.具体做法:step1:用辅助数组dp表示前i个数的译码方式有多少种。

step2:对于一个数,我们可以直接译码它,也可以将其与前面的1或者2组合起来译码:

如果直接译码,则dp[i] = dp[i - 1];如果组合译码,则dp[i] = dp[i - 2]。

step3:对于只有一种译码方式的,选上种dp[i - 1]即可,对于满足两种译码方式(10,20不能)则是dp[i - 1] + dp[i - 2]

step4:依次相加,最后的dp[length]即为所要求答案。

3.注意不能解码的情况(前面不是1和2但是后面接着的数字是0,因为0在26个字母中没有对应的字母,所以不能解码)返回0

三、具体步骤

使用的语言是C

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 解码
 * @param nums string字符串 数字串
 * @return int整型
 */
 // a b c d e f g h i j  k  l   m  n  o  p  q  r  s  t  u  v  w  x  y  z
 // 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
int solve(char* nums ) {
    // write code here
    int len = strlen(nums);
    if(len == 0) return 0;
    if(len == 1 && nums[0] == '0') return 0; 
    int* dp = (int*)malloc(sizeof(int) * len);
    // 第一位数字不管是几,都只有一种译码结果。
    dp[-1] = 1;
    dp[0] = 1;
    for(int i = 1; i < len; i++) {
        // 如果前一位数字是1
        if(nums[i - 1] == '1') {
            // 后一位数字是0,那么只有一种组成10
            if(nums[i] == '0') {
                dp[i] = dp[i - 2];
            } else { //如果后一位数字是非0的数字那么可以和前面的1组合也可以自己单独作为一个字母
                dp[i] = dp[i - 1] + dp[i - 2];
            }
        } else if(nums[i - 1] == '2') {
            // 如果前一位数字是2
            if(nums[i] == '0') { // 后一位数字是0,那么只能组合
                dp[i] = dp[i - 2];
            } else if(nums[i] >= '1' && nums[i] <= '6') {
                // 如果后一位数字在1和6之间,那么即可以组合也可以单独
                dp[i] = dp[i - 1] + dp[i - 2];
            } else{
                // 如果后一位数字是7-9,那么只能单独
                dp[i] = dp[i - 1];
            }
        } else {
            // 如果前一位数字不是1和2,但是后一位数字是0的时候我们认为不能译码
            if(nums[i] == '0') return 0;
            // 如果前一位数字不是1和2,那么不能组合,只有一种方式
            dp[i] = dp[i - 1];
        }
    }
    return dp[len - 1];
}

你可能感兴趣的:(面试,职场和发展)