目录
l剑指 Offer 46. 把数字翻译成字符串力扣版本
把数字翻译成字符串_牛客题霸_牛客网牛客版
滚动数组优化
跳台阶【一】 (大数取模)一 八个零七
最小花费爬楼梯
l剑指 Offer 46. 把数字翻译成字符串力扣版本
给定一个数字,按照对应的格式把数字转化为字符串,我把线性dp的题做多了,竟然对于这种青蛙跳台阶的变式题竟然不会了
状态F(i):表示前i个数字的翻译方法
转移方程的推导:开始了我的固定思维模式,给出一个i位置,然后从头定义j位置,然后分为前j个位置的方法个数+F(j+1, i)的二维遍历模式,然而没有理清题意,之前的回文串分割、公共串等都是需要从头定义二维的dp模式,然而这道题仅需处理i位置的前俩个位置元素即可
F(i) = F(i-2)+F(i-1)(在这俩个数组成的数字大于等于10小于等于25即可)
F(i-1) (不满足上方条件)
初始化dp数组大小为nums.size()+1
dp[0] = dp[1] = 1;
#include<stdlib.h>
class Solution {
public:
int translateNum(int num) {
// 转为字符串
string str = to_string(num);
int n = str.size();
// 初始化dp数组全为1,至少每个数字转化为一种
vector<int> dp(n+1, 1);
for(int i = 2; i <= n; i++)
{
int temp = 10*(str[i-2]-'0')+(str[i-1]-'0');
// 如果前俩个组成的数字在【0, 25】
if(temp>=10 && temp<=25)
dp[i] = dp[i-1]+dp[i-2];
else
dp[i] = dp[i-1];
}
return dp[n];
}
};
把数字翻译成字符串_牛客题霸_牛客网牛客版
有一种将字母编码成数字的方式:'a'->1, 'b->2', ... , 'z->26'。
现在给一串数字,返回有多少种可能的译码结果
这俩个版本不同之处就是牛客上面这个是不能存在0的,并且当为10或者20只能是一种翻译结果,而且超出了26以上的双位或以上的数都不满足例如 100,50,(即当遇到0的时候前面只能为1或者2,如果是别的数那就无法进行翻译)
class Solution {
public:
/**
* 解码
* @param nums string字符串 数字串
* @return int整型
*/
int solve(string nums) {
// write code here
int n = nums.size();
if(nums[0]=='0')
return 0;
if(nums=="10" || nums=="20")
return 1;
for(int i = 1; i < n; i++)
if(nums[i] == '0')
if(nums[i-1]!='1' && nums[i-1]!='2')
return 0;
vector<int> dp(n+1, 1);
for(int i = 2;i <= n; i++)
{
int temp = 10*(nums[i-2]-'0')+(nums[i-1]-'0');
if((temp>10 && temp<20) || (temp>20&&temp<=26))
dp[i] = dp[i-1]+dp[i-2];
else
dp[i] = dp[i-1];
}
return dp[n];
}
};
滚动数组优化
当然也可以使用滚动数组来进行优化,是一种思想,只用到前面俩个元素的值,完全就可以不需要构建一整个数组。即用三个变量就可以完成一整个功能
#include<stdlib.h>
class Solution {
public:
int translateNum(int num) {
// 转为字符串
string str = to_string(num);
int n = str.size();
// 初始化dp数组全为1,至少每个数字转化为一种
int dp1 = 1;
int dp2 = 1;
int max = 1;
for(int i = 2; i <= n; i++)
{
int temp = 10*(str[i-2]-'0')+(str[i-1]-'0');
// 如果前俩个组成的数字在【0, 25】
if(temp>=10 && temp<=25)
max = dp1+dp2;
else
max = dp1;
dp2 = dp1;
dp1 = max;
}
return max;
}
};
跳台阶【一】 (大数取模)一 八个零七
class Solution {
public:
int numWays(int n) {
int dp1 = 1;
int dp2 = 1;
int max = 1;
for(int i = 2; i <= n; i++)
{
max = (dp1+dp2)%1000000007;
dp1 = dp2;
dp2 = max;
}
return max;
}
};
【最小花费爬楼梯】
给定一个整数数组 cost cost ,其中 cost[i] cost[i] 是从楼梯第i i 个台阶向上爬需要支付的费用,下标从0开始。一旦你支付此费用,即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。
请你计算并返回达到楼梯顶部的最低花费。
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
// write code here
int n = cost.size();
vector<int> dp(n+1, 0);
for(int i = 2; i <= n; i++)
{
dp[i] = min(dp[i-2]+cost[i-2], dp[i-1]+cost[i-1]);
}
return dp[n];
}
};