LeetCode:91. 解码方法(python)

LeetCode:91. 解码方法(python)

一条包含字母 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) 。

LeetCode 链接


思路:动态规划
  • 状态:从字符串头部遍历至尾部

  • 选择:罗列 s[i] 字符的解码值情况,dp[i] 保存字符串从头部到 i 位置解码的总数。

    • 考虑 i 处字符与 i-1 处字符结合,主要分析 0 字符的不同情况:

      • 若为 0030、40、50... 则无法解码,可直接返回 0
      • 若为 01~09 的情况,则 i 处字符不能与前一位结合,则只有单字符解码的情况,即 dp[i]=dp[i-1]
      • 若为 10、20 的情况,则 i 处字符必须与前一位结合,则为双字符解码,即 dp[i]=dp[i-2]
      • 若为 11~19、21~26 的情况,则 i 处字符既可以单字符解码,也可以双字符解码,因此 dp[i]=dp[i-2]+dp[i-1]
      • 剩余为 27~29、31~39、41~49... 的情况只可以单字符解码,即 dp[i]=dp[i-1]
    • 图示如下:

      在这里插入图片描述

  • 遍历:判断 i 处字符解码情况需要考虑前一位字符,因此从字符串 i=1 处开始遍历。

  • 初始化

    • 字符串从 i=1 处开始遍历,该字符处可单字符解码和双字符解码的方法数都为 1,即 dp[i-2]=1、dp[i-1]=1,则多添加一位数方便计算,设置 dp=[1,1]
附代码(Python3):
class Solution:
    def numDecodings(self, s):
        if not s or s[0]=='0':    # s 为空或 s 头部为 '0' 则返回 0
            return 0
        
        dp = [1, 1]                # 初始化 dp  
        for i in range(1, len(s)):
            if s[i-1:i+1] == '00' or (s[i]=='0' and s[i-1]>'2'):    # 直接返回 0 的情况(00、30、40....)
                return 0
            if '1'<=s[i-1:i+1]<='26' and s[i]!='0':                 # 可单字符和双字符解码的情况(11~19、21~26)
                dp.append(dp[-2]+dp[-1])
            elif s[i]=='0':                                          # 只能双字符解码的情况(10、20)
                dp.append(dp[-2])
            else:
                dp.append(dp[-1])                                     # 只能单字符解码的情况(01~09、27~29、31~39...)
                
        return dp[-1]
test = Solution()
s_li = ["12", "226", "24726"]
for s in s_li:
    print(test.numDecodings(s))
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
给定一个整数数组 nums 和一个目标值 target,要求在数组中找出两个数的和等于目标值,并返回这两个数的索引。 思路1:暴力法 最简单的思路是使用两层循环遍历数组的所有组合,判断两个数的和是否等于目标值。如果等于目标值,则返回这两个数的索引。 此方法的时间复杂度为O(n^2),空间复杂度为O(1)。 思路2:哈希表 为了优化时间复杂度,可以使用哈希表来存储数组中的元素和对应的索引。遍历数组,对于每个元素nums[i],我们可以通过计算target - nums[i]的值,查找哈希表中是否存在这个差值。 如果存在,则说明找到了两个数的和等于目标值,返回它们的索引。如果不存在,将当前元素nums[i]和它的索引存入哈希表中。 此方法的时间复杂度为O(n),空间复杂度为O(n)。 思路3:双指针 如果数组已经排序,可以使用双指针的方法来求解。假设数组从小到大排序,定义左指针left指向数组的第一个元素,右指针right指向数组的最后一个元素。 如果当前两个指针指向的数的和等于目标值,则返回它们的索引。如果和小于目标值,则将左指针右移一位,使得和增大;如果和大于目标值,则将右指针左移一位,使得和减小。 继续移动指针,直到找到两个数的和等于目标值或者左指针超过了右指针。 此方法的时间复杂度为O(nlogn),空间复杂度为O(1)。 以上三种方法都可以解决问题,选择合适的方法取决于具体的应用场景和要求。如果数组规模较小并且不需要考虑额外的空间使用,则暴力法是最简单的方法。如果数组较大或者需要优化时间复杂度,则哈希表或双指针方法更合适。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值