首页 > 其他分享 >leetcode day06 动态规划之解码方法I和II

leetcode day06 动态规划之解码方法I和II

时间:2024-09-10 19:24:07浏览次数:10  
标签:return int 解码 day06 II 字符串 fi 方法 leetcode

91.解码方法

该题类似于爬楼梯

方法一:动态规划

对于给定的字符串 s,设它的长度为 n,其中的字符从左到右依次为 s[1],s[2],⋯,s[n]。我们可以使用动态规划的方法计算出字符串 s 的解码方法数。

具体地,设 f i 表示字符串 s 的前 i 个字符 s[1..i] 的解码方法数。在进行状态转移时,我们可以考虑最后一次解码使用了 s 中的哪些字符,那么会有下面的两种情况:

*  第一种情况是我们使用了一个字符,即 s[i] 进行解码,那么只要 s[i] !=0,它就可以被解码成 A∼I 中的某个字母。由于剩余的前 i−1 个字符的解码方法数为 f i−1​,因此我们可以写出状态转移方程:

                                                         fi​=fi−1​,其中 s[i] !=0

*  第二种情况是我们使用了两个字符,即 s[i−1] 和 s[i] 进行编码。与第一种情况类似,s[i−1] 不能等于 0,并且 s[i−1] 和 s[i] 组成的整数必须小于等于 26,这样它们就可以被解码成 J∼Z 中的某个字母。由于剩余的前 i−2 个字符的解码方法数为 f i−2 ,因此我们可以写出状态转移方程:

                                        fi​=fi−2​,其中 s[i−1] !=0 并且 10⋅s[i−1]+s[i]≤26

 需要注意的是,只有当 i>1 时才能进行转移,否则 s[i−1] 不存在。

将上面的两种状态转移方程在对应的条件满足时进行累加,即可得到 fi​ 的值。在动态规划完成后,最终的答案即为 fn​。

注意:动态规划的边界条件为: 

                                                               f0 = 1

即空字符串可以有 1 种解码方法,解码出一个空字符串。

class Solution {
public:
    int numDecodings(string s) {
        int n = s.size();
        vector<int> f(n+1);
        f[0] = 1; //空字符串
        for(int i=1;i<=n;i++){
            if(s[i-1]!='0'){
                f[i] += f[i-1];
            }
            if(i>1 && s[i-2]!='0' && ((s[i-2]-'0')*10 + (s[i-1]-'0')<=26 )){
                f[i] += f[i-2];
            }
        }
        return f[n];
    }
};

639  解码方法II

这里要分多种情况讨论。

 

因为这里总共两类,且每一类的情况很多,需要重复书写的地方也很多,故而可以采用两个函数,分别返回int值,这样就会显得简洁明了。而且便于更改。

class Solution{
private:
    static constexpr int mod = 1000000007;
    int check1(char ch){
        if(ch=='0'){
            return 0;
        }
        return ch == '*'?9:1;
    }
    int check2(char c0,char c1){
        if (c0 == '*' && c1 == '*') {
            return 15;
        }
        if (c0 == '*') {
            return c1 <= '6' ? 2 : 1;
        }
        if (c1 == '*') {
            if (c0 == '1') {
                return 9;
            }
            if (c0 == '2') {
                return 6;
            }
            return 0;
        }
        return c0 != '0' && (c0 - '0') * 10 + (c1 - '0') <= 26;
    }
public:
    int numDecodings(string s){
        int n = s.size();
        int a = 0, b = 1, c = 0;
        // c 表示 f[i], b = f[i-1], a=f[i-2];
        for (int i = 1; i <= n; ++i) {
            c = (long long)b * check1(s[i - 1]) % mod;
            if (i > 1) {
                c = (c + (long long)a * check2(s[i - 2], s[i - 1])) % mod;
            }
            a = b;
            b = c;
        }
        return c;
    }
};

标签:return,int,解码,day06,II,字符串,fi,方法,leetcode
From: https://blog.csdn.net/m0_73682715/article/details/142104257

相关文章

  • LeetCode之数组/字符串
    88.合并两个有序数组classSolution{publicvoidmerge(int[]nums1,intm,int[]nums2,intn){//这个循环将nums2中的元素逐个复制到nums1中从索引m开始的位置for(inti=0;i<n;i++){nums1[i+m]=nums2[i];......
  • Day06.Java流程控制2
    Java流程控制循环结构While循环while(布尔表达式){//循环内容}最基本的循环只要布尔表达式为true,循环就会一直执行下去我们大多数情况会让循环停止下来,我们需要一个让表达式失效的方式来结束循环少数情况需要循环一直执行,比如服务器的请求响应监听等循环条件一直......
  • LeetCode: 2552. 统计上升四元组 动态规划 时间复杂度O(n*n)
    2552.统计上升四元组today2552.统计上升四元组题目描述给你一个长度为n下标从0开始的整数数组nums,它包含1到n的所有数字,请你返回上升四元组的数目。如果一个四元组(i,j,k,l)满足以下条件,我们称它是上升的:0<=i<j<k<l<n且nums[i]<nums[k]<num......
  • 115. 不同的子序列(leetcode)
    https://leetcode.cn/problems/distinct-subsequences/submissions/563375885/这题比较有难度,具体不太好想到,需要以是否选择s[i]来划分子集这位描述的很清楚,不做过多赘述classSolution{publicintnumDistinct(Strings,Stringt){//f[i][j]表示s中前i个......
  • 每日算法随笔:反转链表 II
    明白了!下面我将基于你给的两种方法来详细解释题解,并展示每一步的变化过程。题解:反转链表II这道题要求我们反转链表中从第left个节点到第right个节点的部分,返回反转后的链表。我们会使用两种方法:递归和迭代。示例解析示例1:输入:head=[1,2,3,4,5],left=2,ri......
  • Leetcode3264. K 次乘运算后的最终数组 I
    EverydayaLeetcode题目来源:3264.K次乘运算后的最终数组I解法1:模拟操作:遍历数组nums,找到其中的最小值x,如果存在多个最小值,选择最前面的一个。将它乘以multiplier。共执行k次操作。代码:/**@lcapp=leetcode.cnid=3264lang=cpp**[3264]K次乘运算......
  • Leetcode3265. 统计近似相等数对 I
    EverydayaLeetcode题目来源:3265.统计近似相等数对I解法1:枚举暴力枚举数组nums中下标i和j满足i<j的nums[i]和nums[j],判断它们是否近似相等。细节:先对数组nums升序排序,在判断它们是否近似相等,转成字符串进行比较,且只交换较大数的数位。代码:/**@l......
  • 【算法题】13.罗马数字转整-力扣(LeetCode)
    【算法题】13.罗马数字转整-力扣(LeetCode)1.题目下方是力扣官方题目的地址13.罗马数字转整数罗马数字包含以下七种字符:I,V,X,L,C,D和M。字符数值I1V5X10L50C100D5......
  • PARTIII-Oracle事物管理-数据并发性和一致性
    9.数据并发性和一致性本章解释了Oracle数据库如何在多用户数据库环境中维护一致性的数据。本章包含以下部分:数据并发性和一致性的介绍Oracle数据库事务隔离级别的概述Oracle数据库锁定机制的概述自动锁定的概述手动数据锁定的概述用户定义锁的概述9.1.数据并发性和一......
  • Day11 二叉树 part01| LeetCode
    理论基础二叉树的种类满二叉树完全二叉树二叉搜索树平衡二叉搜索树存储方式:数组、链式二叉树的遍历方式深度优先遍历前序(递归法、迭代法)中序(递归法、迭代法)后序(递归法、迭代法)广度优先遍历层序(迭代法)二叉树的定义publicclassTreeNode{......