小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
题目
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
来源:力扣(LeetCode)
思路
1.考虑使用动态规划,dp[i]表示使用字符i-1能有多少种翻译方法,如果i-1与i-2组成的字符串小于"25",那么说明这种组合可行,否则只有单独翻译i-1这一种组合
2.判断条件i-1和i-2字符组成的要大于等于10并且小于等于25
temp.compareTo("10") >= 0 && temp.compareTo("25") <= 0
3.可以使用几个变量代替数组的形式存储状态,减少空间消耗。
代码
动态规划版
public int translateNum1(int num) {
String s = String.valueOf(num);
int n = s.length();
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
String temp = s.substring(i - 2, i); //注意这里取得是s.charAt(i-2)和s.charAt(i-1)
dp[i] = dp[i - 1];
if (temp.compareTo("10") >= 0 && temp.compareTo("25") <= 0) {
// System.out.println("abc");
dp[i] += dp[i - 2];
}
}
return dp[n];
}
空间使用优化
由于每次求dp[i]的过程只和dp[i-1]以及dp[i-2],所以可以使用pre1,pre2来代替,节省了n的空间
class Solution {
public int translateNum(int num) {
String s = String.valueOf(num);
int n = s.length();
int pre1 = 1;//表示dp[i-1]
int pre2 = 1;//表示dp[i-2]
for (int i = 2; i <= n; i++) {
String temp = s.substring(i - 2, i);
int cur = pre1;
if (temp.compareTo("10") >= 0 && temp.compareTo("25") <= 0) {
// System.out.println("abc");
cur += pre2;
}
pre2 = pre1;
pre1 = cur;
}
return pre1;
}
}