题目链接:剑指offer46
相似题目:力扣91,LeetCode91-解码方法-acrafle的博客
题意
给定一个正整数,要求将该正整数翻译成字符串,翻译规则如下:
- 0==>>A
- 1==>>B
- ...
- 25==>>Z
问可以有多少种翻译方式
思路
可以用搜索,也可以用动态规划。
搜索思路:
- 挨个匹配数字,每次可以匹配1位或者2位数字,匹配2位数字时要判断当前数字小于25
- 匹配完往下一步搜索,直到搜索到字符串末尾,ans++
- 需要使用记忆化搜索,即对于每一个位置,如果搜索过,则直接返回该位置上面的答案,避免重复搜索导致超时
动态规划:
- 转移方程:dp[i]=dp[i-1]*c1+dp[i-2]*c2
- 其中c1和c2是需要根据匹配的字符串判定的条件
- c1表示前1位数字可以翻译成一个字符
- 在本题中,c1恒成立,因为任意一个一位数都有对应的字符。
- c2表示前两位数字可以翻译成一个字符
- 在本题中,只有前两位数字小于等于25,才能够进行翻译
- 即,
- c2==1,int(s[i-2:i])≤25
- c2==0,int(s[i-2:i])>25
- c1表示前1位数字可以翻译成一个字符
代码(Golang)
此处代码套用了lc91的代码,把题中给的数字转换成字符串然后开始dp。
func translateNum(num int) int {
s:=strconv.FormatInt(int64(num),10)
return numDecodings(s)
}
func numDecodings(s string) int {
dp:=make([]int,len(s)+1)
dp[0]=1
for i:=1;i<=len(s);i++{
if digit(s[i-1:i]){
dp[i]+=dp[i-1]
}
if i>1 && digit(s[i-2:i]){
dp[i]+=dp[i-2]
}
}
return dp[len(s)]
}
func digit(s string)bool{
if len(s)==2 && s[0]=='0'{
return false
}
now,_:=strconv.Atoi(s)
if now<26 && now>=0{
return true
}
return false
}