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

在这里插入图片描述

解法 动态规化

以12256为例从左边开始翻译可以分为两个子问题:翻译1,2256,翻译12,256;2256可以分解为翻译2,256 | 22,56。256可以分解为翻译2,56。由上分析可以使用递归求解但是存在重复部分“56”,所以考虑由下至上解决问题,这样可以消除子问题假设 f ( i ) f(i) f(i)是第i个数开始存在的翻译数则 f ( i ) = f ( i + 1 ) + g ( i , i + 1 ) f ( i + 2 ) f(i) = f(i+1) + g(i,i+1)f(i+2) f(i)=f(i+1)+g(i,i+1)f(i+2)其中 g ( i , i + 1 ) g(i,i+1) g(i,i+1)表示第i与第i+1个数合并后在10~25的范围内为1否则为0。代码如下:

class Solution {
    public int translateNum(int num) {
        if(num < 0) return 0;
        String numberInString = String.valueOf(num);
        return translateNum(numberInString);
    }
    private int translateNum(String numberInString) {
        int len = numberInString.length();
        // 记录f(i), 从第i个数字开始有多少种翻译方式
        int[] counts = new int[len];
        int count = 0;
        for(int i = len - 1; i >= 0; --i) {
            if(i < len - 1)
                // f(i) = f(i+1)
                count = counts[i+1];
            else
                // f(i) = 1, 末尾数字只有一种翻译方法
                count = 1;
            if(i < len - 1) {
                int digit1 = numberInString.charAt(i) - '0';
                int digit2 = numberInString.charAt(i+1) - '0';
                int combine = digit1 * 10 + digit2;
                if(combine <= 25 && combine >= 10) {
                    if(i < len - 2)
                        // f(i) = f(i+1) + f(i+2)
                        count += counts[i+2];
                    else
                        count+=1;
                }
            }
            counts[i] = count;
        }
        count = counts[0];
        return count;
    }
}
posted @ 2020-09-09 08:30  消灭猕猴桃  阅读(77)  评论(0编辑  收藏  举报