剑指Offer:第十天:动态规划(中等)

剑指 Offer 46. 把数字翻译成字符串

动态规划:
方法一:字符串遍历
    1.先将num转成字符串,方便后续处理,因为我们需要精确到每一位数字
    2.状态定义:dp[i]:以s[i-1]为结尾的数字(即从头开始总共i位数)的翻译方案数量,
    3.转移方程:s[i-1]s[i]组成的两位数字可以被翻译,则dp[i]=dp[i-1]+dp[i-2];否则,dp[i]=dp[i-1]
    4.注意:如果s[i-1]=0,组成的两位数无法被翻译;因此翻译范围:10~25(包括边界)
    5.定义初始状态:dp[0]=dp[1]=1;dp[0]表示无数字的时候。
    6.那么dp[0]=1从何而来呢?
      6.1 s[0]和s[1]组成两位数属于10~25时,dp[2]=2,而dp[2]=dp[1]+dp[0] => dp[0]=1;
	  6.2 s[0]和s[1]组成两位数不属于10~25时,dp[2]=dp[1]=1,不关dp[0]的事
    7.由于从始至终我们只需要3个变量:dp[i],dp[i-1],dp[i-2],因此我们用变量c,b,a分别去对应这三个状态,
      从而减少空间的开销
class Solution {
public:
    int translateNum(int num) {
        //先将num转字符串,方便后续处理
        string numStr=to_string(num);
        //定义dp[0]
        int a=1;
        //定义dp[1]
        int b=1;
        //从i=2开始,即开始算dp[2],即以s[2-1]结尾的数
        for(int i=2;i<=numStr.length();i++){
            string tmpStr=numStr.substr(i-2,2);
            int tmpVal=atoi(tmpStr.c_str());
            int c=tmpVal>=10&&tmpVal<=25?a+b:b;
            a=b;
            b=c;
        }
        return b;
    }
};

方法二:数字求余
相比于方法一,方法二少了额外的整数转字符串的空间开销,只用了常数个变量就完成了
class Solution {
public:
    int translateNum(int num) {
        int a=1,b=1;
        //从右向左计算翻译数量
        while(num>9){
            int c=num%100>=10&&num%100<=25?a+b:a;
            b=a;
            a=c;
            num/=10;
        }
        return a;
    }
};

剑指 Offer 48. 最长不含重复字符的子字符串

方法一:滑动窗口
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        //用于判断字符c是否已经存在于哈希表中了
        unordered_set<char>st;
        //s的长度
        int length=s.length();
        //记录最长无重复字符子串的长度
        int maxLen=0;
        //用于滑动
        int right=-1;
        //遍历字符串
        for(int i=0;i<length&&right+1<length;i++){
            if(i!=0){
                st.erase(s[i-1]);
            }
            while(right+1<length&&st.count(s[right+1])==0){
                st.insert(s[right+1]);
                right++;
            }
            maxLen=max(maxLen,right-i+1);
        }
        return maxLen;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jomo.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值