题目
给定一个数字,我们按照如下规则把它翻译位字符串:0 = ‘a’; 1 = ‘b’;…; 25 = ‘z’,一个数字可能有多种翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
例:
12258,有5种翻译:“bccfi”, “bwfi”, “bczi”, “mcfi”, “mzi”。
思路
- 按书上理解,每一位数字有2种可能,单独翻译和与后一位合并翻译,因此f(i) = f(i+1) + g(i,i+1)*f(i+2),g(i,i+1)是一个指示器,当nums[i-1:i+1]在10~25中时为1,否则为0。
- 时间复杂度:O(2^n),最差每一位都有2个分支
- 空间复杂度:O(n),最大迭代深度
- 书上为了避免迭代时处理公共子问题而重复计算,选择从后向前翻译。实际上是不需要的,因为有公式f(i) = f(i-1) + g(i,i+1)* f(i-2)。我们从前向后依次翻译,每一位都有2种翻译方式,独立翻译或者和前一位结合。其实本质上就是一个动态规划,和跳台阶、斐波那契数列是一回事。
- 时间复杂度:O(n)
- 空间复杂度:O(1)
代码
思路2:时间复杂度:O(n),空间复杂度:O(1)
def trans_nums_to_strs(nums):
"""
:param nums: number
:return: number of translations
"""
nums = str(nums)
cache = [1, 1] # sol(n-2), sol(n-1)
for i in range(1, len(nums)):
if 9 < int(nums[i-1:i+1]) < 26:
cache[1], cache[0] = cache[0] + cache[1], cache[1]
else:
cache[0] = cache[1]
return cache[1]
思考
相似的题目
[LeetCode 91. 解码方法]
题目
一条包含字母 A-Z 的消息通过以下方式进行了编码:
‘A’ -> 1
‘B’ -> 2
…
‘Z’ -> 26
给定一个只包含数字的非空字符串,请计算解码方法的总数。
示例 1:
输入: “12”
输出: 2
解释: 它可以解码为 “AB”(1 2)或者 “L”(12)。
示例 2:
输入: “226”
输出: 3
解释: 它可以解码为 “BZ” (2 26), “VF” (22 6), 或者 “BBF” (2 2 6) 。
代码
class Solution:
def numDecodings(self, s):
"""
:type s: str
:rtype: int
"""
if s[0] == '0':
return 0
nums = s
cache = [1, 1]
for i in range(1, len(nums)):
if nums[i] == '0':
if nums[i-1] in ['1', '2']:
cache[0], cache[1] = 0, cache[0]
else:
return 0
elif 10 < int(nums[i-1:i+1]) <= 26:
cache[1], cache[0] = cache[0] + cache[1], cache[1]
else:
cache[0] = cache[1]
return cache[1]
注意:此题主要区别在于字母对应是从1开始的,也就是’0’是非法字符,注意处理有’0‘的情况即可。