剑指offer——Day10动态规划(中等)

Day10 2022.11.16 动态规划(中等)

46.把数字翻译成字符串

自己实现

想到每种数字组成会很复杂,就放弃了,其实题目已经说了是两位数的组合,就还好。

题解

动态规划。首先,动态规划表dp[i]代表以xi为结尾的翻译方案数量。

  • 若xi和xi-1组成的两位数字可以被翻译,则dp[i] = dp[i-1] + dp[i-2] ;
  • 若不能被翻译,则dp[i] = dp[i-1]

其中,可以被翻译的两位数区间为[10, 25](因为当xi-1 = 0时,组成的两位数是无法被翻译的,eg:00,01...)

因此:转移方程为1668587625603

初始状态为dp[0] = d[1] = 1,即没有数字和第一位数字的时候是一种情况

以最后状态为结束,在下列代码中即为a的值

代码如下:

class Solution {
public:
    int translateNum(int num) {
        string str=to_string(num);
        int a=1;
        int b=1;
        int i;
        for(i=2;i<=str.length();i++)
        {
            string tmp=str.substr(i-2,2);
            int c=(tmp>="10"&&tmp<="25"?a+b:a);
            b=a;
            a=c;
        }
        return a;
    }
};

代码表现

hint:

  • 这个题还是没做出来,多想一想。别害怕它的复杂,其实细想还好

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

自己实现

终于自己做出来了!其实就从最开始遍历字符串,dp[i]代表以xi结尾的最长子字符串长度,这样的话就正好能找到之前连续的最长的字符串直接find()了。

然后如果断了,就从从之前那个字符串找到相应字符的位置开始接上

代码如下:

class Solution {
public:
	int lengthOfLongestSubstring(string s) {
		if (s.size() == 0)return 0;
		vector<int> vec;
		vec.push_back(1);
		int i;
		int max = 1;
		for (i = 1; i < s.size(); i++)
		{
			int len_front = vec[i - 1];
			string str = s.substr(i - len_front, len_front);
			if (str.find(s[i]) != str.npos)
			{

				if (vec[i - 1] > max)max = vec[i - 1];
				vec.push_back(len_front-str.find(s[i]));
			}
			else
			{
				vec.push_back(vec[i - 1] + 1);
				if (vec[i] > max)max = vec[i];
			}
		}
		return max;
	}
};

代码表现

hint:

  • dp[i]是以xi为结尾的连续……
posted @ 2022-11-16 17:38  神鹏佐佑  阅读(14)  评论(0)    收藏  举报