标签:strong 输入 port enum 下标 ret package href 要求
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"
? 对数字的每一位,都有两种选择:走1步(翻译一个数字)或者走2步(翻译两个数字)。因此我们可以在草稿纸上画出一个树的结构。
? 仔细分析上图,我们可以看出,有许多重复计算的地方。
? 如果在递归算法中反复求解同堂的子问题,我们就把这种性质称作重叠子问题。这是适合用动态规划方法求解的最优化问题应该具备的性质。
? 因此我们就可以想到利用动态规划来求解问题。
? 动态规划的空间复杂度一般为O(n),实际上对于很多问题都有提升的空间。例如本题:我们不需要存储所有下标为i的数字翻译方式。只需要得到i为最后一位的结果。在此过程中,只需要不断更新i-2,i-1位置上的结果就满足要求。这就是利用滚动数组思想来降低动态规划的时间复杂度。
package main
import (
"fmt"
"strconv"
)
// 直接递归
func translateNum1(num int) int {
str := strconv.Itoa(num)
var dfs func(str string, index int) int
dfs = func(str string, index int) int {
if index >= len(str) - 1 {
return 1
}
temp := int(str[index] - ‘0‘) * 10 + int(str[index + 1] - ‘0‘)
if temp >= 10 && temp <= 25 {
return dfs(str, index + 1) + dfs(str, index + 2)
} else {
return dfs(str, index + 1)
}
}
return dfs(str, 0)
}
// 递归加备忘
func translateNum2(num int) int {
str := strconv.Itoa(num)
memo := make([]int, len(str))
var dfs func(str string, index int) int
dfs = func(str string, index int) int {
if index >= len(str) - 1 {
return 1
}
if memo[index] != 0 {
return memo[index]
}
temp := int(str[index] - ‘0‘) * 10 + int(str[index + 1] - ‘0‘)
if temp >= 10 && temp <= 25 {
memo[index] = dfs(str, index + 1) + dfs(str, index + 2)
} else {
memo[index] = dfs(str, index + 1)
}
return memo[index]
}
return dfs(str, 0)
}
// 自底向上
func translateNum3(num int) int {
str := strconv.Itoa(num)
n := len(str)
// dp[i]保存前i个数有多少中翻译方式
dp := make([]int, n + 1) // 多存储一位,以方便理解
dp[0] = 1
dp[1] = 1
for i := 2; i < n + 1; i++ {
temp := int(str[i - 2] - ‘0‘) * 10 + int(str[i - 1] - ‘0‘)
if temp >= 10 && temp <= 25 {
dp[i] = dp[i - 2] + dp[i - 1]
} else {
dp[i] = dp[i - 1]
}
}
return dp[n]
}
// 利用滚动数组压缩空间复杂度
func translateNum4(num int) int {
str := strconv.Itoa(num)
n := len(str)
prev := 1
cur := 1
for i := 2; i < n + 1; i++ {
temp := int(str[i - 2] - ‘0‘) * 10 + int(str[i - 1] - ‘0‘)
if temp >= 10 && temp <= 25 {
tmp := cur
cur = prev + cur
prev = tmp
} else {
prev = cur
}
}
return cur
}
【LeetCode每日一题】2020.6.9 面试题46. 把数字翻译成字符串
标签:strong 输入 port enum 下标 ret package href 要求
原文地址:https://www.cnblogs.com/enmac/p/13081443.html