题解 | #把数字翻译成字符串#

把数字翻译成字符串

https://www.nowcoder.com/practice/046a55e6cd274cffb88fc32dba695668

题意理解

  • 数组中的所有数字都必须参与译码,并且数字范围是[1, 26]。
  • 两位数组合应该在[10, 26]之间,并且是十位数,如02的组合也是无效的。
  • 0作为单数字译码肯定是无效的,0和其他数字组合作为译码时,只有10和20这个组合可以在[10, 26]范围内译码,其他情况都是无效的,此时这个数组就无法译码,译码方式为0。
  • 当新加入一个数字时,这个数字可以作为单数字译码,也可以和左边的数字组合后再译码,但这两种译码方式都必须满足[1, 26]范围。

最小子问题

  • 当数组中只有一个数字时,只有一种译码方式,但要保证这个数字不是0,此时dp[0]=1。
  • 其他所有位置的初始译码方式都为0,这是为了考虑数字中含有0的情况。

如何思考状态转移方程?

  • 当前位置如果作为单数字译码,则和前面一位数字作为末尾的译码方式一样,此时dp[i] = dp[i-1]
  • 当前位置如果和前面一位数字作为组合译码,则译码方式还应该加上前面两位数字作为末尾的方式,因此dp[i] += dp[i-2]

状态转移方程的推导过程

https://blog.nowcoder.net/n/6e9d8904d9fe44808c1474e4ea4d2583

/**
 * 解码
 * @param nums string字符串 数字串
 * @return int整型
 */
function solve( nums ) {
    // write code here
    const dp = new Array(nums.length).fill(0);
    

    if (!nums.startsWith("0")) {  // 有可能只传入一个0,也有可能传入开头为0的字符串
        dp[0] = 1;
    }

    for (let i = 1; i < nums.length; ++i) {
        if (nums[i] !== "0") {  // 当前位置作为单数字译码,只需要求当前数字不为0,为0的话当前位置有0种译码方式
            dp[i] == dp[i-1];
        }
        // if (nums[i] === "0") {
        //     if (nums[i-1] !== "1" && nums[i-1] !== "2")
        //         return 0;
        // }
        const tempNum = Number(nums[i-1]+nums[i]);
        if (tempNum >=10 && tempNum <= 26) {  // 当前位置作为组合数字译码,数字范围要在10到26,如果前面位置是0,当前位置也是0,同样不满足当前情况,当前位置有0种译码方式
            i === 1 ? dp[i] += 1 : dp[i] += dp[i-2];  // 要考虑只有i=1时只有两个数字的情况
        }  // 如果字符串是1001,00组合无效,最后的0位置的译码方式为0,01组合也无效,最后1位置的译码方式等于前面0的译码方式,即0
    }

    return dp[nums.length - 1];
}
module.exports = {
    solve : solve
};

全部评论

相关推荐

喜欢走神的孤勇者练习时长两年半:爱华,信华,等华,黑华
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务