首页 > 试题广场 >

数字字符转化为字母组合的种数

[编程题]数字字符转化为字母组合的种数
  • 热度指数:3164 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个字符串str,str全部由数字字符组成,如果str中的某一个或者相邻两个字符组成的子串值在1~26之间,则这个子串可以转换为一个字母。规定‘1’转换为“A”,“2”转换为“B”......"26"转化为“Z“。请求出str有多少种不同的转换结果,由于答案可能会比较大,所以请输出对取模后的答案。

输入描述:
输出一行仅有’0‘~’9‘组成的字符串,代表str 


输出描述:
输出一个整数,代表你所求出的取模后答案。
示例1

输入

1111

输出

5

说明

能转换出来的结果有:“AAAAA”,“LAA”,“ALA”,“AAL”,“LL”。 
示例2

输入

01

输出

0

说明

“0”没有对应的字符,而“01”是不可转换的。 
示例3

输入

18

输出

2

备注:
时间复杂度,空间复杂度
动态规划求解,从左往右试,可以粗略分为以下两种情况
  1. 如果str[i-1]是1,我们需要考虑当前位置str[i]str[i-1]构成个两位数的转化,如果str[i-1]是2,且str[i]为0~6,我们同样需要考虑当前位置str[i]和前一个位置str[i-1]组合成两位数进行转化,需要加上到str[i-2]为止的组合数。此时的状态转移方程为:dp[i]=dp[i-1]+dp[i-2]
  2. 如果前一个位置是0,或者前一个位置是2,且当前位置是大于6的数,那直接从前面的状态转移过来,状态转移方程为:dp[i]=dp[i-1]
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br  = new BufferedReader(new InputStreamReader(System.in));
        char[] str = br.readLine().toCharArray();
        if(str.length == 0 || (str.length == 1 && str[0] == '0')) {
            System.out.println(0);        // 一个0转化不成字母
        }else if(str.length == 1){
            System.out.println(1);        // 一个非零数字只能有一种转化
        }else{
            int[] dp = new int[str.length + 1];
            dp[0] = 1;        // 没有字符,初始化为1
            for(int i = 0; i < str.length; i++){
                dp[i + 1] = str[i] == '0'? 0: dp[i];
                // 如果前一个字符是1,或者前一个字符是2且当前字符是0~6,就可以和前一个字符组成两位数的字母转化
                if(i > 0 && (str[i - 1] == '1' || str[i - 1] == '2' && str[i] <= '6')) {
                    dp[i + 1] += dp[i - 1];
                    dp[i + 1] %= 1000000007;
                }
            }
            System.out.println(dp[dp.length - 1]);
        }
    }
}

发表于 2021-11-18 15:23:22 回复(0)