ms-hot29 解码方法

leetcode原题链接: 解码方法

ms-hot目录: ​​​​​​ ms-hot目录

上一篇 :ms-hot28 合并两个有序数组

下一篇:二叉树的中序遍历

题目描述

一条包含字母 A-Z 的消息通过以下映射进行了 编码 :

"1" -> 'A'
"2" -> 'B'
...
"25" -> 'Y'
"26" -> 'Z'

然而,在 解码 已编码的消息时,你意识到有许多不同的方式来解码,因为有些编码被包含在其它编码当中("2" 和 "5" 与 "25")。

例如,"11106" 可以映射为:

  • "AAJF" ,将消息分组为 (1, 1, 10, 6)
  • "KJF" ,将消息分组为 (11, 10, 6)
  • 消息不能分组为 (1, 11, 06) ,因为 "06" 不是一个合法编码(只有 "6" 是合法的)。

注意,可能存在无法解码的字符串。

给你一个只含数字的 非空 字符串 s ,请计算并返回 解码 方法的 总数 。如果没有合法的方式解码整个字符串,返回 0。

题目数据保证答案肯定是一个 32 位 的整数。

示例 1:

复制代码
输入:s = "12"
输出:2
解释:它可以解码为 "AB"(1 2)或者 "L"(12)。

示例 2:

复制代码
输入:s = "226"
输出:3
解释:它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。

示例 3:

复制代码
输入:s = "06"
输出:0
解释:"06" 无法映射到 "F" ,因为存在前导零("6" 和 "06" 并不等价)。

给你一个只含数字的 非空 字符串 s ,请计算并返回 解码 方法的 总数 。如果没有合法的方式解码整个字符串,返回 0。

题目数据保证答案肯定是一个 32 位 的整数。

示例 1:

复制代码
输入:s = "12"
输出:2
解释:它可以解码为 "AB"(1 2)或者 "L"(12)。

示例 2:

复制代码
输入:s = "226"
输出:3
解释:它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。

示例 3:

复制代码
输入:s = "06"
输出:0
解释:"06" 无法映射到 "F" ,因为存在前导零("6" 和 "06" 并不等价)。

提示:

  • 1 <= s.length <= 100
  • s 只包含数字,并且可能包含前导零。

解题方法:动态规划DP。

  1. 问题定义: dpi表示以第i个字符结尾的解码方法数,则申请n+1大小的dp数组。

  2. 初始化:

dp0=1

如果s1 >= '1' and s1<='9' ==> dp1=1; 否则dp1=0

  1. 状态转移方程:考虑点是si是单独解码,还是si-1, si两个字符一起解码。

1)如果si单独解码:则dpi+1 = dpi+1 + dpi --注意最开始的时候dpi+1默认值为0;

2)如果si和si-1一起解码,则需要判断si-1和si组成的数组num是否满足 1 <= num <= 26这个条件,如果满足这个条件,则dpi+1 = dpi+1 + dpi-1。

  1. 返回解:最后求到的dpn即为以最后一个字符结尾的解码数,即为问题的解。
C++代码
cpp 复制代码
#include <iostream>
#include <string>
#include <vector>
class Solution {
public:
    int numDecodings(string s) {
        int n = s.size();
        if (n == 0) {
            return 0;
        }
        vector<int> dp(n + 1, 0); //dp[i]表示以第i个字符结尾的字符串对应的解码方法数
        dp[0] = 1; //初始化:空字符串解码数为1(即解码出一个空字符串)
        dp[1] = (s[0] >= '1' && s[0] <= '9') ? 1 : 0;
        for (int i = 1; i < n; i++) {
            int cur = s[i] - '0';
            int pre = s[i - 1] - '0';
            if (cur >= 1) { //考虑s[i]单独解码
                dp[i + 1] += dp[i];
            }
            if (pre == 1 ||(pre == 2 && cur <= 6) ) { //考虑s[i]和s[i-1]一起解码
                dp[i + 1] += dp[i - 1];
            }
        }
        return dp[n];
    }
};
相关推荐
左手の明天8 小时前
SLIP 协议封装与解析详解:原理、C 代码与实战案例
linux·c语言·开发语言·c++
海上小飞龙8 小时前
【KMP算法-下篇】同一道题:Java 库函数 2600 微秒,手写 KMP 16 微秒
java·开发语言·算法
青少儿编程课堂8 小时前
后缀自动机解析:本质不同子串与最长重复片段统计
c++·python·算法·bfs·信息学竞赛
朝朝辞暮i8 小时前
C++ 第 12 课:局部变量、作用域、变量生命周期
开发语言·c++·算法
乐迪信息10 小时前
港口船舶逆行怎么管?AI防爆摄像机搭载智能检测算法
大数据·人工智能·深度学习·算法·计算机视觉
无名猿10 小时前
shared_ptr 完全指南:引用计数、控制块与开销
c++·性能优化·内存管理·标准库·现代c++
Sirens.10 小时前
Java并发锁详解:六类锁策略与 synchronized 底层原理
java·前端·算法
和裕11 小时前
全纸结构重型纸箱能否满足 1 吨以上设备出口熏蒸豁免要求?通关合规性全解析
大数据·运维·网络·人工智能·算法
tangguofeng11 小时前
不带头结点的链队操作集(不含InitFlag)(C语言版)
算法