题目所述就是把一串数字反向解码为字母映射出来,有多少种方法。 题目也说,一个单独的数字可以映射的,但是这个数字前面是0的话就不可以。
来看看题目给的示例: 226就有三种解码方式:它可以解码为 “BZ” (2 26), “VF” (22 6), 或者 “BBF” (2 2 6)
优化:处理边界以及初始化问题 多开一个虚拟位置,有什么用呢? 在旧的初始化列表中,初始化dp[1]是比较麻烦的,如果把它放在填表位置就会比较轻松。
得注意:1. 保证虚拟节点位置值是正确的;2.得注意下标映射关系 当要在新的dp表里面2的结果就要用到0和1位置的值。这里dp[0]=1,要想在2位置解码成功,那么0位置必须是解码成功的。 在新的dp表里面的i统一都对应把位置往后面移动了一位,这里在写代码的时候就得减1。
class Solution {
public:
int numDecodings(string s) {
int n=s.size();
vector<int> dp(n);
dp[0]=s[0]!='0';
if(n==1)return dp[0];
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;
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];
}
};
优化后:
class Solution {
public:
int numDecodings(string s) {
int n=s.size();
vector<int> dp(n+1);
dp[0]=1;
dp[1]=s[1-1]!='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];
}
};
题目要求不能回退,就是不能往左和往上。 如果有3*2个表格:那么到达就有三种情况:
所以可以先初始化这些可能初始化的位置。还可以在外面先虚拟一些空间,让下面这些就不会越界:
这些虚拟空间的值要保证后面填表顺序是正确的,要想填表正确,虚拟空间值设置就是:
class Solution {
public:
int uniquePaths(int m, int n) {
vector<vector<int>> dp(m + 1, vector<int>(n + 1));
dp[0][1] = 1;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
return dp[m][n];
}
};
题目与上面的类型是相同的,就是多了一个障碍物。
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m=obstacleGrid.size(),n=obstacleGrid[0].size();
vector<vector<int>> dp(m + 1, vector<int>(n + 1));
dp[0][1] = 1;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
if(obstacleGrid[i-1][j-1]==0)
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
return dp[m][n];
}
};
有问题请指出,大家一起进步!!!