一、使用最小花费爬楼梯
题目链接:746. 使用最小花费爬楼梯 - 力扣(LeetCode)
题目:给你一个整数数组 cost
,其中 cost[i]
是从楼梯第 i
个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。你可以选择从下标为 0
或下标为 1
的台阶开始爬楼梯。请你计算并返回达到楼梯顶部的最低花费。
示例一:输入:cost = [10,15,20] 输出:15
示例二:输入:cost = [1,100,1,1,1,100,1,1,100,1] 输出:6
先来分析一下题目:判断一下顶部的位置
根据我们的动规算法原理逐步分析:
a. 状态表示
根据题目要求判断,dp[i] 表示到达 i 位置时的最小花费。
b. 状态转移方程
用之前或之后的状态,推导出 dp[i] 的值。
c.初始化
初始化是为了保证填表时不越界。
d. 填表顺序
有题目和图可知,要知道后面的就必须先算出前面的,所以,填表顺序:从左往右。
e. 返回值
由状态表示可知,返回值为 dp[n] 。
编写代码:
class Solution {
public:int minCostClimbingStairs(vector<int>& cost) {int n=cost.size();//1、创建dp表vector<int> dp(n+1);//2、初始化dp[0]=dp[1]=0;//填表for(int i=2;i<=n;++i){dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);}return dp[n];}
};
二、解码方法
题目链接: 91. 解码方法 - 力扣(LeetCode)
题目:一条包含字母 A-Z
的消息通过以下映射进行了编码 :
"1" -> 'A'
"2" -> 'B'
...
"25" -> 'Y'
"26" -> 'Z'
然而,在解码已编码的消息时,你意识到有许多不同的方式来解码,因为有些编码被包含在其它编码当中("2"
和 "5"
与 "25"
)。
例如,"11106"
可以映射为:
"AAJF"
,将消息分组为(1, 1, 10, 6)
"KJF"
,将消息分组为(11, 10, 6)
- 消息不能分组为
(1, 11, 06)
,因为"06"
不是一个合法编码(只有 "6" 是合法的)。
注意,可能存在无法解码的字符串。给你一个只含数字的 非空 字符串 s ,请计算并返回 解码方法的总数 。如果没有合法的方式解码整个字符串,返回 0
。
示例一:输入:s="12" 输出:2
示例二:输入:s="226" 输出:3
示例三:输入:s="06" 输出:0
先来分析一下题目给的示例:
a. 状态表示
根据题目判断:
b. 状态转移方程
根据最近的一步来划分问题
c. 初始化
d. 填表顺序 ---从左向右
e. 返回值 ---dp[n-1]
编写代码:
class Solution {
public:int numDecodings(string s) {int n=s.size();//1、创建dp表vector<int> dp(n);//2、初始化dp[0]=s[0]!='0'; //dp[0]的情况//处理只有一个字符的情况if(n==1) return dp[0];//dp[1]的情况if(s[0]!='0'&&s[1]!='0') dp[1]+=1;int t=(s[0]-'0')*10+(s[1]-'0');if(t>=10&&t<=26) dp[1]+=1;//3、填表for(int i=2;i<n;++i){if(s[i]!='0') dp[i]+=dp[i-1];int t=(s[i-1]-'0')*10+(s[i]-'0');if(t>=10&&t<=26) dp[i]+=dp[i-2];}return dp[n-1];}
};
优化方案:
在上面代码中,我们发现了,有部分代码,相似度非常高,而且我们在进行初始化的时候,好像有点麻烦,那有没有什么办法,能简化一下呢?
在我们增加虚拟节点的值时要注意:
1、虚拟节点的值,要保证后面的填表是正确的
2、要注意下标的映射关系
编写优化方案代码:
class Solution {
public:int numDecodings(string s) {int n=s.size();vector<int> dp(n+1);dp[0]=1;//保证后面的填表是正确的dp[1]=s[0]!='0'; //要注意下标的映射关系for(int i=2;i<=n;++i){if(s[i-1]!='0') dp[i]+=dp[i-1];int t=(s[i-2]-'0')*10+(s[i-1]-'0');if(t>=10&&t<=26) dp[i]+=dp[i-2];}return dp[n];}
};