1269-停在原地的方案数

题目

1269. 停在原地的方案数 - 力扣(LeetCode) (leetcode-cn.com)

思路

我们从最后一步开始考虑,最后一步需要到达0, 则上一步必定到达1或者0,更一般地说如果第s步到达了p,那么第s-1步必须到达p - 1或者p或者p + 1。所以,如果我们能够分别知道第s - 1步到达p, p - 1p + 1的方案数量,那么第s步到达p的方案数量就是第s - 1步到达p, p - 1p + 1的方案数量的总和。

根据上述分析,我们需要从第0步开始,求出第s (0 <= s <= steps)步到达各个位置p的方案数量,我们使用数组dp[s][p]来表示这个数量。可以知道(如果p - 1p + 1越界则不进行累加)

dp[s][p] = dp[s - 1][p - 1] + dp[s - 1][p] + dp[s - 1][p + 1]

对于step=0的初始情况,有

dp[0][0] = 1
dp[0][p] = 0 (p != 0)

最终的答案即为dp[steps][0](第steps步到达0的方案数目)。

可以看到,我们在计算和使用dp时仅使用了dp[s]dp[s-1](计算第s步仅使用第s-1步的结果),因此dp数组的第一维度长度可以设置为2而不是steps + 1。这时候对于第s步,在dp数组中索引为index = (i + 2) % 2, 第s-1步在dp数组中索引为index = (i + 1) % 2

另外,根据题目中每个步骤尽可以+1或者-1,并且起始位置为0我们可以知道不考虑数组长度的情况下,最远的psteps - 1, 同时考虑数组长度的限制,则有 0 <= p < min(steps, arrLen),因此,根据题目给的数据范围,p最大值为499 (500 - 1),因此dp数组的第二个维度最大长度500,相比arrLen (10 ^ 6)就很小了。

代码

class Solution {
public:
    int numWays(int steps, int arrLen) {
        return dp_solve(steps, arrLen);
    }

    // 递归搜索,会超时
    int dfs(int steps, int end, int des) {
        int total = 0;
        if (steps == 0) {
            if (des == 0) {
                total += 1;
            }
            return total;
        }
        if (des > 0) {
            total += find(steps - 1, end, des - 1);
        }
        if (des < end) {
            total += find(steps - 1, end, des + 1);
        }
        total += find(steps - 1, end, des);
        return total;
    }
	
    // 动态规划
    int dp_solve(int step, int arrLen) {
        long long dp[2][500];
        int end = min(step, arrLen);
        for(int i=0; i<end; i++) {
            dp[0][i] = 0;
        }
        dp[0][0] = 1;
        for(int i=1; i<=step; i++) {
            int index = (i + 2) % 2;
            int index_last = (i + 1) % 2;
            for (int j=0; j<end; j++) {
                long long total = 0;
                if (j > 0) {
                    total += dp[index_last][j - 1];
                }
                if (j < end - 1) {
                    total += dp[index_last][j + 1];
                }
                total += dp[index_last][j];
                dp[index][j] = total % (1000000007);
            }
        }
        return dp[step % 2][0];
    }
};

总结

本题中需要搜索的最长数组长度为right_end = min(step, arrLen),我在编写程序的过程中有个地方把 right_endstep弄混了,导致数组越界访问,但没有触发数组越界的保护机制,因此在运行时就出现答案时对时错的情况,花了不少时间才找到错误ಥ_ಥ.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值