每日算法一练:剑指offer——动态规划(2)

1. 解密数字

现有一串神秘的密文 ciphertext,经调查,密文的特点和规则如下:

密文由非负整数组成
数字 0-25 分别对应字母 a-z
请根据上述规则将密文 ciphertext 解密为字母,并返回共有多少种解密结果。

示例 1:

输入: ciphertext = 216612
输出: 6
解释: 216612 解密后有 6 种不同的形式,分别是 "cbggbc","vggbc","vggm","cbggm","cqgbc" 和 "cqgm" 

提示:

0 <= ciphertext < 231

        这个问题可以通过动态规划来解决。我们需要找出一种方法,将一个给定的数字 ciphertext 转化为对应的翻译方式,具体翻译规则是:

  1. 每个数字(1-9)可以被单独翻译。
  2. 由两个数字组成的两位数(10-25)也可以翻译为一个字符。

动态规划解题思路

  1. 定义状态
    dp[i] 表示到数字的第 i 位时,所有可能的翻译方法数。我们需要计算 dp[n],其中 nciphertext 的位数。

  2. 转移方程

    • 对于每一位数字 x[i],如果它与前一位数字 x[i-1] 组成的两位数在 [10, 25] 范围内,则可以将这两位数作为一个字符翻译。因此,状态转移公式为:

      dp[i]=dp[i−1]+dp[i−2]dp[i] = dp[i-1] + dp[i-2]

      其中:

      • dp[i-1] 表示当前位数字单独翻译的情况。
      • dp[i-2] 表示当前位数字与前一位数字组成的两位数翻译的情况(如果符合条件)。
    • 如果 x[i-1]x[i] 组成的两位数不在 [10, 25] 范围内,则:

      dp[i]=dp[i−1]dp[i] = dp[i-1]
  3. 初始化

    • dp[0] = 1,表示“无数字”的翻译方法数。
    • dp[1] = 1,表示仅有一个数字时的翻译方法数。
  4. 最后的结果
    结果是 dp[n],即数字 ciphertext 的翻译方案数。

代码实现

方法一:字符串遍历

class Solution {
    public int crackNumber(int ciphertext) {
        String s = String.valueOf(ciphertext); // 将数字转换为字符串
        int a = 1, b = 1; // 初始状态 dp[0] = 1, dp[1] = 1
        for(int i = 2; i <= s.length(); i++) {
            String tmp = s.substring(i - 2, i); // 获取当前位和前一位的两位数
            int c = (tmp.compareTo("10") >= 0 && tmp.compareTo("25") <= 0) ? a + b : a; // 判断是否在可翻译的范围内
            b = a; // 更新 dp[i-1]
            a = c; // 更新 dp[i]
        }
        return a; // 返回 dp[n]
    }
}

方法二:数字求余

        为了节省空间,我们可以直接利用数字的除法和取余操作来获取每一位数字。这个方法通过从右到左进行动态规划,避免了字符串的使用。

class Solution {
    public int crackNumber(int ciphertext) {
        int a = 1, b = 1, x, y = ciphertext % 10; // 获取个位数字
        while
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值