【DP】LeetCode 剑指 Offer 46. 把数字翻译成字符串

题目链接

剑指 Offer 46. 把数字翻译成字符串

思路

这个问题与 dp 中的经典问题“跳台阶”问题十分类似,在跳台阶问题中我们是选择跳一个台阶或者两个台阶,而在这个问题中我们是选择再统计一个字符还是再统计两个字符。即我们在遍历到第 i 个字符的时候,可以把它当做前面 i1 个字符接上一个字符或者是前面 i2 个字符接上两个字符。

举个栗子:

比如有一串数字为 12212
当我们遍历到 1221 时,我们可以看做两种情况:

  • 122 的后面接上了 1
  • 12 的后面接上了 21

所以1221的映射方法应该是122的映射方法数加上12的映射方法数,所以状态转移方程应该包含 dp[i]=dp[i1]+dp[i2]

这里我们把末尾两字符的值记为 value

只不过在跳台阶问题中我们无论怎样都能跳两个台阶,在该问题中需要满足 10value25 才能满足这两个字符能映射到字母,所以取 dp[i2] 的值是有条件的。如果不满足条件,说明这种分割方法中的 value 没法映射到对应字母,即应该舍去 dp[i2],此时状态方程变为 dp[i]=dp[i1],即此时没法视为在 i2 个字符的基础上接两个字符。

举个栗子:

比如有一串数字为 12345
当我们遍历到 1234 时,我们可以看做两种情况:

  • 123 的后面接上了 4
  • 12 的后面接上了 34

但是 34 已经超过了 25,所以它没有映射的字母,需要把这种情况舍去。

综上所述,状态转移方程应该为:

dp[i]={dp[i1],value<10,dp[i1]+dp[i2],10value25.

代码

dp数组版

class Solution {
    public int translateNum(int num) {
        // dp[i] = dp[i - 1] + dp[i - 2]
        String string = String.valueOf(num);
        if(string.length() == 1){
            return 1;
        }

        int[] dp = new int[string.length()];

        dp[0] = 1;
        dp[1] = Integer.valueOf(string.substring(0, 2)) > 25 ? 1 : 2;
        for(int i = 2; i < string.length(); i++){
            String subString = string.substring(i - 1, i + 1);
            int value = Integer.valueOf(subString);
            if(10 <= value && value <= 25){
                dp[i] = dp[i - 1] + dp[i - 2];
            }else{
                dp[i] = dp[i - 1];
            }
        }
		
        return dp[string.length() - 1];
    }
}

空间优化版

class Solution {
    public int translateNum(int num) {
        // dp[i] = dp[i - 1] + dp[i - 2]
        String string = String.valueOf(num);
        if(string.length() == 1){
            return 1;
        }

        int pre = 1;
        int pre2 = Integer.valueOf(string.substring(0, 2)) > 25 ? 1 : 2;
        int next = pre2;
        for(int i = 2; i < string.length(); i++){
            String subString = string.substring(i - 1, i + 1);
            int value = Integer.valueOf(subString);
            if(10 <= value && value <= 25){
                next = pre + pre2;
            }else{
                next = pre2;
            }
            pre = pre2;
            pre2 = next;
        }

        return next;
    }
}
posted @   Frodo1124  阅读(28)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示