剑指 Offer 46. 把数字翻译成字符串(动态规划)
剑指 Offer 46. 把数字翻译成字符串
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
示例 1:
输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"
提示:
0 <= num < 231
方法一:(常规动态规划,时间和空间复杂度均为O(n))
1 class Solution { 2 public: 3 // dp[i] 表示前i个字符有多少种翻译 4 // 状态转移方程:dp[i] = dp[i - 1](当s[i]单独翻译),dp[i] = dp[i - 2] + dp[i - 1](当s[i]和s[i - 1]可以组合翻译时) 5 int translateNum(int num) { 6 string s = to_string(num); 7 int n = s.size(); 8 vector<int> dp(n + 1); // dp[i] 表示前i个字符有多少种翻译 9 dp[0] = 1; 10 dp[1] = 1; 11 for (int i = 2; i <= n; i++) { 12 if (s[i - 2] == '1' || (s[i - 2] == '2' && s[i - 1] <= '5')) { 13 dp[i] = dp[i - 2] + dp[i - 1]; 14 } else { 15 dp[i] = dp[i - 1]; 16 } 17 } 18 return dp[n]; 19 } 20 };
方法二:(优化后的动态规划,时间复杂度O(n),空间复杂度O(1))
1 class Solution { 2 public: 3 // dp[i]表示前i个字符可以翻译的方法 4 // 状态转移方程: 5 // dp[i] = dp[i - 1] (当s[i]单独翻译时), 6 // dp[i] = dp[i -2] + dp[i - 1] (当s[i - 1]和s[i]可以结合翻译时) 7 int translateNum(int num) { 8 string s = to_string(num); 9 int n = s.size(); 10 vector<int> dp(n + 1); // 由于用到dp[n]所以数组开大一个 11 dp[0] = 1; 12 dp[1] = 1; 13 for (int i = 2; i <= n; i++) { 14 // 当s[i - 1]和s[i]可以结合翻译时 15 if (s[i - 2] == '1' || (s[i - 2] == '2' && s[i - 1] <= '5')) { 16 dp[i] = dp[i - 2] + dp[i - 1]; 17 } else { // 当s[i]只能单独翻译时 18 dp[i] = dp[i - 1]; 19 } 20 } 21 return dp[n]; 22 } 23 };
浙公网安备 33010602011771号