给定一个字符串str,str全部由数字字符组成,如果str中的某一个或者相邻两个字符组成的子串值在1~26之间,则这个子串可以转换为一个字母。规定‘1’转换为“A”,“2”转换为“B”......"26"转化为“Z“。请求出str有多少种不同的转换结果,由于答案可能会比较大,所以请输出对
取模后的答案。
输出一行仅有’0‘~’9‘组成的字符串,代表str。
输出一个整数,代表你所求出的取模后答案。
1111
5
能转换出来的结果有:“AAAAA”,“LAA”,“ALA”,“AAL”,“LL”。
01
0
“0”没有对应的字符,而“01”是不可转换的。
18
2
时间复杂度,空间复杂度
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]);
}
}
} 动态规划
(1) 第 i 个字符单独转换为 字母(和第一种情况一样) (2) 结合第 i-1 个字符,组合转换为 字母,如果是这种情况,那么,需要找出第 i-1 个字符单独转换为 字母 的方案数。因此,这种情况下,方案数 与 第 i-1 个字符单独转换为字母的方案数相同。
递推式
// 第 i 个字符只能单独转换为一个 字母 // dp[i-1] :第 i 个字符单独转换的方案数 dp[i]=dp[i-1]; // 第 i 个字符 可以和 第 i-1 个字符 共同转换为一个 字母 // dp[i-1] :第 i 个字符单独转换的方案数 // dp[i-2] :第 i 个字符,结合第 i-1 个字符组合转换为一个字母的方案数 dp[i]=dp[i-1]+dp[i-2];
题解
public class Main {
private static String num;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
num = in.next();
num = "0" + num;
System.out.println(findLetter());
}
private static int findLetter() {
int[] dp = new int[num.length() + 1];
// 初始化 1:表示第 1 个字符只能有 1 种转换情况
dp[0] = 1;
for (int i = 1; i < num.length(); ++i) {
// 判断第 i 个字符能够转换为 字母的情况
// 0 不能转换
// 1 第 i 个字符只能单独转换为一个字母
// 2 第 i 个字符能够结合第 i-1 个字符转换为 一个字母
int judge = judge(i);
if (judge == 0) {
return 0;
}
if (judge == 1) {
// dudge=1
dp[i] = dp[i - 1];
} else {
// judge=2
dp[i] = (dp[i - 1] + dp[i - 2]) % 1000000007;
}
}
return dp[num.length() - 1];
}
// 判断第 i 个字符能够转换为 字母的情况
private static int judge(int i) {
int count = 0;
if (num.charAt(i) >= '1' && num.charAt(i) <= '9') {
// 能够单独转换
count++;
}
if (num.charAt(i - 1) != '0') {
int letter = Integer.valueOf(num.substring(i - 1, i + 1));
if (letter >= 10 && letter <= 26) {
// 能够结合第 i-1 个字符一起转换
count++;
}
}
return count;
}
}
import java.util.Scanner;
public class Main{
public static void main(String[] args){
final long A = 1000000007;
Scanner input = new Scanner(System.in);
String inputString = input.nextLine();
// 如果长度为0或者首字符为0,直接返回
if (inputString.length() == 0 || inputString.charAt(0) == '0') {
System.out.println(0);
return;
}
int length = inputString.length();
long fn = 1;
long fn_1 = 1;
long fn_2 = 1; // 初始值要设对,可以通过长度为2的字符串来验证
for (int i = 1; i < length; ++i){
fn_2 = fn_1;
fn_1 = fn;
fn = 0;
if (inputString.charAt(i) != '0'){
// i这一位单独可以转换
fn += fn_1;
}
int c = (inputString.charAt(i - 1) - '0') * 10 + (inputString.charAt(i) - '0');
if (c >= 10 && c <= 26){
// i和i-1可以组合转换
fn += fn_2;
}
if (fn == 0) {
// 如果某个fn为0,那么结果一定为0
break;
}
fn %= A;
}
System.out.println(fn);
}
} #include <bits/stdc++.h>
using namespace std;
const int M = 1000000007;
int main(){
string s;
cin>>s;
int l = s.length(), p=1;
int cnt = (s[l-1]=='0'?0:1);
for(int i=l-2;i>=0;i--){
if(s[i]=='0'){
p = cnt;
cnt = 0;
}else{
int t = cnt;
if((10*(s[i]-'0')+s[i+1]-'0')<=26)
cnt = (cnt+p)%M;
p = t;
}
}
cout<<cnt<<endl;
return 0;
} #include<bits/stdc++.h>
using namespace std;
int main()
{
string s;
cin>>s;
int cur = s[s.size() - 1] == '0' ? 0 : 1;
int next = 1, tmp = 0;
for (int i = s.size() - 2; i >= 0; i--){
if (s[i] == '0'){
next = cur;
cur = 0;
}
else{
tmp = cur;
if ((s[i] - '0') * 10 + s[i + 1] - '0' < 27)
cur = (cur+next)%1000000007;
next = tmp;
}
}
cout<< cur%1000000007;
return 0;
} import java.util.*;
public class Main {
public static int mod = (int)1e9 + 7;
public static void main (String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
System.out.println(dpComboNum(s));
}
/*
public static long getComboNum (char[] arr, int index) {
if (index == arr.length)
return 1;
if (arr[index] == '0')
return 0;
if (arr[index] == '1') {
long res = getComboNum(arr, index+1) % mod;
if (index + 1 < arr.length) {
res += getComboNum(arr, index+2) % mod;
}
return res % mod;
}
if (arr[index] == '2') {
long res = getComboNum(arr, index+1) % mod;
if (index + 1 < arr.length && (arr[index+1] >= '0' && arr[index + 1] <= '6')) {
res += getComboNum(arr, index+2) % mod;
}
return res % mod;
}
return getComboNum(arr, index+1) % mod;
}*/
public static int dpComboNum(String strs) {
if (strs == null || strs.charAt(0) == '0' || strs.length() == 0)
return 0;
int n = strs.length();
int[] dp = new int[n+1];
dp[n] = 1;
for (int i = n-1; i >= 0; i--) {
dp[i] = dp[i+1];
if (strs.charAt(i) == '0')
dp[i] = 0;
if (strs.charAt(i) == '1') {
if (i + 1 < n) {
dp[i] = (dp[i] + dp[i+2]) % mod;
}
}
if (strs.charAt(i) == '2') {
if (i + 1 < n && (strs.charAt(i+1) >= '0' && strs.charAt(i+1) <= '6')) {
dp[i] = (dp[i] + dp[i+2]) % mod;
}
}
}
return dp[0];
}
} #include<iostream>
#include<cstring>
using namespace std;
const int mod = 1e9+7;
int proccess(string &s,int i) {
if (i==s.size()) return 1;
if (s[i] == '0') return 0;
int res = proccess(s, i+1) % mod;
if(i+1 < s.size()) {
int num = (s[i]-'0')*10 + s[i+1]-'0';
if(num>=0 && num <=26) res = (res + proccess(s,i+2) ) % mod;
}
return res;
}
int main() {
string s;
cin>>s;
int n = s.size();
if(s[0]==0) {
puts("0");
return 0;
}
int res = proccess(s,0);
cout << res << endl;
} #include<cstdio>
(802)#include<cstring>
const int mmax=100010;
char str[mmax];
int dp[mmax];
int main(){
scanf("%s",str+1);
dp[0]=1;
if(str[1]!='0')
dp[1]=1;
//printf("%d",strlen(str+1));
for(int i=2;i<=strlen(str+1);++i){
if(str[i]!='0'){
dp[i]=(dp[i]+dp[i-1])%1000000007;
}
int sum=(str[i-1]-'0')*10+str[i]-'0';
if(sum>=10&&sum<=26){
dp[i]=(dp[i]+dp[i-2])%1000000007;
}
//printf("%d %d\n",i,dp[i]);
}
printf("%d",dp[strlen(str+1)]);
}