题目链接:leetcode.
还以为是回溯,看了提示说是动态规划,那我就瞎写写吧
28 / 31 个通过测试用例
超时
class Solution {
public:
int numWays(int steps, int arrLen) {
vector<vector<int>> dp(steps, vector<int>(arrLen, 0));
dp[0][0] = 1;
dp[0][1] = 1;
for(int i = 1;i < steps;++i)
{
for(int j = min(i + 1, arrLen - 1);j >= 0;--j)
{
dp[i][j] += dp[i - 1][j] % 1000000007;
dp[i][j] %= 1000000007;
if(j > 0)
{
dp[i][j] += dp[i - 1][j - 1] % 1000000007;
dp[i][j] %= 1000000007;
}
if(j < arrLen - 1)
{
dp[i][j] += dp[i - 1][j + 1] % 1000000007;
dp[i][j] %= 1000000007;
}
}
}
return dp[steps - 1][0];
}
};
官解优化了一下动规矩阵的宽度
/*
执行用时:76 ms, 在所有 C++ 提交中击败了20.34%的用户
内存消耗:12.7 MB, 在所有 C++ 提交中击败了42.37%的用户
*/
class Solution {
const int M = 1000000007;
public:
int numWays(int steps, int arrLen) {
//最多跳到steps的位置
int len = min(steps, arrLen);
vector<vector<int>> dp(steps, vector<int>(len, 0));
dp[0][0] = 1;
dp[0][1] = 1;
for(int i = 1;i < steps;++i)
{
for(int j = 0;j < len;++j)
{
dp[i][j] += dp[i - 1][j];
if(j > 0)
{
dp[i][j] = (dp[i - 1][j - 1] + dp[i][j]) % M;
}
if(j < len - 1)
{
dp[i][j] = (dp[i - 1][j + 1] + dp[i][j]) % M;
}
}
}
return dp[steps - 1][0];
}
};
评论里说还能再优化一下,宽度最长为steps/2,因为要过去再回来
/*
执行用时:36 ms, 在所有 C++ 提交中击败了48.30%的用户
内存消耗:9.8 MB, 在所有 C++ 提交中击败了55.93%的用户
*/
class Solution {
const int M = 1000000007;
public:
int numWays(int steps, int arrLen) {
//最多跳到steps的位置
int len = min(steps / 2 + 1, arrLen);
vector<vector<int>> dp(steps, vector<int>(len, 0));
dp[0][0] = 1;
dp[0][1] = 1;
for(int i = 1;i < steps;++i)
{
for(int j = 0;j < len;++j)
{
dp[i][j] += dp[i - 1][j];
if(j > 0)
{
dp[i][j] = (dp[i - 1][j - 1] + dp[i][j]) % M;
}
if(j < len - 1)
{
dp[i][j] = (dp[i - 1][j + 1] + dp[i][j]) % M;
}
}
}
return dp[steps - 1][0];
}
};
本文解析了一道LeetCode题目,采用动态规划算法求解在给定步数内到达数组特定位置的方法数量。通过逐步优化,从初步实现到最后精简版,显著提升了执行效率。
365

被折叠的 条评论
为什么被折叠?



