美文网首页算法学习
算法题--计算字符串的解码方式数

算法题--计算字符串的解码方式数

作者: 岁月如歌2020 | 来源:发表于2020-04-26 15:46 被阅读0次
image.png

0. 链接

题目链接

1. 题目

A message containing letters from A-Z is being encoded to numbers using the following mapping:

'A' -> 1
'B' -> 2
...
'Z' -> 26
Given a non-empty string containing only digits, determine the total number of ways to decode it.

Example 1:

Input: "12"
Output: 2
Explanation: It could be decoded as "AB" (1 2) or "L" (12).

Example 2:

Input: "226"
Output: 3
Explanation: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).

2. 思路1:动态规划

  • 字符串!算极值!果断想到动态规划
  • 先考虑以下例子:
1    -> 结果 1(1)
11   -> 结果 2(1 1 和 11)
01   -> 结果 0 说明不能以0开头
100  -> 结果 0 说明0前面不能出现0
30   -> 结果 0 说明0前面不能出现非1非2的其他数
22   -> 结果 2(2 2 和 22)
226  -> 结果 3(2 2 6 和 22 6 和 2 26)

明显结果答案跟数字位数是直接相关的
计 dp[n] = 对前n位数字的解码方式

根据上面的最后两个例子, 可以粗略得出,n = 3时的结果,是在n=2的结果的基础上得出的,具体来说,6有2种选择:

  1. 跟前面1位的2结合
  2. 自己独立成码

当第1种情况发生时, 意味着解码方式跟26左边的数字的解码方式是想同的,因为26已经确定要结合并追加在左边数字后面了, 即dp[n - 2]

当第2种情况发生时, 意味着解码方式跟6左边的数字的解码方式是相同的,因为6已经确定要追加在左边数字后面了,即 dp[n - 1]

粗略看来,6只有这两种可能选择, 所以 dp[n] = dp[n - 1] + dp[n - 2]

于是,动态规划的三要素可以写出了:

  • 重叠子问题: 求dp[n]的时候,需要求dp[i<n]的值, 最终需要求dp[1]的值; 而求dp[n-1]的时候, 也需要求dp[i < n - 1]的值,最终也需要求dp[1]的值, 可见dp[1]是重叠子问题, 同理 dp[2], dp[3], ..., dp[n - 2]都是重叠的子问题
  • 最优子结构: 已知 dp[n - 1] 和 dp[n - 2]即可求出 dp[n], 所以对于dp[n]而言,省去了继续往左探索的需要,且求 dp[n] 的时候,不会影响已经求出的 dp[n - 1] 和 dp[n - 2]的值,满足最优子结构要求
  • 状态转移方程: dp[n] = dp[n - 1] + dp[n - 2]

前面写的这么爽,是否问题就结束了呢?

并没有,可以这么写,是有前提条件的,就是一些边界问题。
意外情况:

  • 若字符串为空或者头部为0, 则整个字符串无法解码
  • s[n - 1]0的话, s[n - 2]的值非12,那么,就没有合法的s[n - 2]来照顾s[n - 1]的0, 这就出现了非法值,导致整个字符串解码失败
  • s[n - 1]=0s[n - 2]12, 此时, s[n - 1]只能跟s[n - 2]结合,而不能独立成码, 此时就少了一种可能性, dp[n] = dp[n - 2]
  • s[n - 1]取值为7~9, 而s[n - 2]12, 意味着 s[n - 1] 不能跟 s[n - 2] 结合, 必须独立成码, 此时就少了一种可能性, dp[n] = dp[n - 1], 而非dp[n] = dp[n - 1]

最后,初始值
定义dp = [0] * (n + 1)
dp[0] = dp[1] = 1

dp[0]是来凑数的,为了dp[2] = dp[1] + dp[0]成立
dp[i]表示从左到右第i个字符

3. 代码

# coding:utf8


class Solution:
    def numDecodings(self, s: str) -> int:
        n = len(s)
        if n == 0:
            return 0
        if n == 1:
            return 0 if s == '0' else 1
        if s[0] == '0':
            return 0

        dp = [0] * (len(s) + 1)
        dp[0] = 1
        dp[1] = 1
        for i in range(1, len(s)):
            if s[i] == '0':
                if s[i - 1] != '1' and s[i - 1] != '2':
                    return 0
                dp[i + 1] = dp[i - 1]
            elif s[i - 1] == '1' or (s[i - 1] == '2' and '1' <= s[i] <= '6'):
                dp[i + 1] = dp[i] + dp[i - 1]
            else:
                dp[i + 1] = dp[i]

        return dp[n]


def my_test(solution, s):
    print('input: s="{}", output: {}'.format(s, solution.numDecodings(s)))


solution = Solution()
my_test(solution, '')
my_test(solution, '0')
my_test(solution, '00')
my_test(solution, '230')
my_test(solution, '1')
my_test(solution, '12')
my_test(solution, '36')
my_test(solution, '202')
my_test(solution, '226')
my_test(solution, '2212')
my_test(solution, '110')

输出结果

input: s="", output: 0
input: s="0", output: 0
input: s="00", output: 0
input: s="230", output: 0
input: s="1", output: 1
input: s="12", output: 2
input: s="36", output: 1
input: s="202", output: 1
input: s="226", output: 3
input: s="2212", output: 5
input: s="110", output: 1

4. 结果

image.png

相关文章

  • 算法题--计算字符串的解码方式数

    0. 链接 题目链接 1. 题目 A message containing letters from A-Z is...

  • decode()

    以encoding指定的方式进行解码,默认字符串编码。 语法: 参数:encoding 执行解码方式errors ...

  • 91. 解码方法

    91. 解码方法 一条包含字母 A-Z 的消息通过以下方式进行了编码: 给定一个只包含数字的非空字符串,请计算解码...

  • 白话 KMP 算法

    KMP 算法是计算机字符串匹配的常规算法。wiki 本篇文章借助简单示例,用通俗易懂的方式描述对 KMP 算法的...

  • 【算法题】14.字符串解码

    题目 给定一个经过编码的字符串,返回它解码后的字符串。 编码规则为: k[encoded_string],表示其中...

  • Python基础-day06

    list ​ 字符串操作 ​ 字典操作 ​ list操作 字符串操作 编码解码 计算机存储数据使用的是...

  • HTML5 video audio属性

    什么是编解码器 编解码器是使用压缩算法对数据的数字流进行编码和解码,使之更适合播放的计算机程序。编解码器的目标通常...

  • 5.C语言的字符串

    以字符数组的方式表示以\0表示结尾 strlen函数:计算字符串长度 计算的是字符数,而不是字数,并且不包括\0它...

  • Decode String

    题目来源s = "3[a]2[bc]", return "aaabcbc".解码字符串的题。然后我搞了搞,代码如下...

  • 遗传算法

    参考文献:知乎遗传算法 编码解码知识 实现遗传算法的第一步就是明确对求解问题的编码和解码方式。对于函数优化问题,一...

网友评论

    本文标题:算法题--计算字符串的解码方式数

    本文链接:https://www.haomeiwen.com/subject/edqjwhtx.html