解码方法、将数字翻译成字符串

1.解码方法

要 解码 已编码的消息,所有数字必须基于上述映射的方法,反向映射回字母(可能有多种方法)。例如,“11106” 可以映射为:
“AAJF” ,将消息分组为 (1 1 10 6)
“KJF” ,将消息分组为 (11 10 6)
题目链接

1.1 动态规划分析求解

在这里插入图片描述

class Solution {
public:
    int numDecodings(string s) {
        if(s.size()==0||s[0]=='0')
        return 0;

        //最少有一个元素,且第一个元素不为0
        vector<int> dp(s.size(),0);
        dp[0]=1;

        for(int i=1;i<s.size();i++)
        {
            if(s[i]=='0')//只能与前面进行组合
            {
                if(s[i-1]>'2'||s[i-1]=='0')//不能进行组合
                return 0;

                if(i>=2)
                dp[i]=dp[i-2];
                else
                dp[i]=1;//第二个元素为0
            }
            else//s[i]!=0
            {
                if(s[i-1]=='1')//前面为1,
                   {
                       if(i-2>=0)
                       dp[i]=dp[i-1]+dp[i-2];
                       else
                       dp[i]=2;//当前为第二个元素
                   }
                else if(s[i-1]=='2'&&s[i]<='6')//前面为2
                    {
                        if(i-2>=0)
                        dp[i]=dp[i-1]+dp[i-2];
                        else
                        dp[i]=2;
                    }
                else
                dp[i]=dp[i-1];
            }
        }
        return dp[s.size()-1];
    }
};

1.2空间复杂度优化

上述代码之中,空间复杂度为O(N),由代码可知,dp[i]只与dp[i-1]和dp[i-2]有关系,因此可以定义三个变量来保存这三个值,使空间复杂度降为O(1)

class Solution {
public:
    int numDecodings(string s) {
        if(s.size()==0||s[0]=='0')
            return 0;
        //dp[i]=dp[i-1]+dp[i-2];
        int first=1;
        int second=1;
        int third=first;

        for(int i=1;i<s.size();i++)
        {
            if(s[i]=='0')
            {
                if(s[i-1]=='0'||s[i-1]>'2')
                    return 0;
                else
                {
                    third=second;
                    second=first;
                    first=third;
                }
            }
            else//s[i]!+'0'
            {
                if(s[i-1]=='1')
                {
                    third=first+second;
                    second=first;
                    first=third;
                }
                else if(s[i-1]=='2'&&s[i]<='6')
                {
                    third=first+second;
                    second=first;
                    first=third;
                }
                else
                    {
                    third=first;
                    second=first;
                    first=second;
                    }
            }
        }
        return third;
    }
};

2.把数字翻译成字符串

给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
题目链接

2.1分析求解

在这里插入图片描述

class Solution {
public:
    int translateNum(int num) {
        if(num==0)
            return 1;

        string str=to_string(num);//将数字转换成字符串
        vector<int> ret(str.size()+1,0);
        ret[0]=1;
        ret[1]=1;

        for(int i=2;i<=str.size();i++)
        {
            if(str[i-2]=='1')
                ret[i]=ret[i-1]+ret[i-2];

            else if(str[i-2]=='2'&&str[i-1]<='5')
                ret[i]=ret[i-1]+ret[i-2];

            else
                ret[i]=ret[i-1];
        }

        return *(ret.end()-1);
    }
};

2.2空间复杂度优化

由上述可知,dp[n]只和dp[n-1]、dp[n-2]有关系,因此可以给定三个变量进行优化

class Solution {
public:
    int translateNum(int num) {
        if(num==0)
            return 1;

        string str=to_string(num);//将数字转换成字符串
       int first=1;
       int second=1;
       int third=1;

        for(int i=1;i<str.size();i++)
        {
            if(str[i-1]=='1')
                third=first+second;

            else if(str[i-1]=='2'&&str[i]<='5')
                third=first+second;

            else
                third=first;

            second=first;
            first=third;
        }

        return third;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值