題目描述(中等难度)

    每个数字对应一个字母,给一串数字,问有几种解码方式。例如 226 可以有三种,2|2|6,22|6,2|26。

    解法一 递归

    很容易想到递归去解决,将大问题化作小问题。

    比如 232232323232。

    对于第一个字母我们有两种划分方式。

    2|32232323232 和 23|2232323232

    所以,如果我们分别知道了上边划分的右半部分 32232323232 的解码方式是 ans1 种,2232323232 的解码方式是 ans2 种,那么整体 232232323232 的解码方式就是 ans1 + ans2 种。可能一下子,有些反应不过来,可以看一下下边的类比。

    假如从深圳到北京可以经过武汉上海两条路,而从武汉到北京有 8 条路,从上海到北京有 6 条路。那么从深圳到北京就有 8 + 6 = 14 条路。

    空间复杂度:

    解法二 递归 memoization

    解法一的递归中,走完左子树,再走右子树会把一些已经算过的结果重新算,所以我们可以用 memoization 技术,就是算出一个结果很就保存,第二次算这个的时候直接拿出来就可以了。

    解法三 动态规划

    同样的,递归就是压栈压栈压栈,出栈出栈出栈的过程,我们可以利用动态规划的思想,省略压栈的过程,直接从 bottom 到 top。

    用一个 dp 数组, dp [ i ] 代表字符串 s [ i, s.len-1 ],也就是 s 从 i 开始到结尾的字符串的解码方式。

    这样和递归完全一样的递推式。

    如果 s [ i ] 和 s [ i + 1 ] 组成的数字小于等于 26,那么

    dp [ i ] = dp[ i + 1 ] + dp [ i + 2 ]

    简单的做法,我们只申请 3 个空间,然后把 dp 的下标对 3 求余就够了。

    然后,如果多考虑以下,我们其实并不需要 3 个空间,我们只需要 2 个就够了,只需要更新的时候,指针移动一下,代码如下。

    从递归,到动态规划,到动态规划的空间复杂度优化,已经很多这样的题了,很经典。

    添加好友一起进步~

    如果觉得有帮助的话,可以点击 给一个 star 哦 ^^

    如果想系统的学习数据结构和算法,强烈推荐一个我之前学过的课程,可以点击 这里 查看详情