码迷,mamicode.com
首页 > 编程语言 > 详细

LeetCode 5274. Number of Ways to Stay in the Same Place After Some Steps - Java - DP

时间:2019-11-24 23:57:47      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:aced   turn   logs   判断   输出   lan   for   ace   output   

题目链接:5274. 停在原地的方案数

You have a pointer at index 0 in an array of size arrLen. At each step, you can move 1 position to the left, 1 position to the right in the array or stay in the same place (The pointer should not be placed outside the array at any time).

Given two integers steps and arrLen, return the number of ways such that your pointer still at index 0 after exactly steps steps.

Since the answer may be too large, return it modulo \(10^9 + 7\).

Example 1:

Input: steps = 3, arrLen = 2
Output: 4
Explanation: There are 4 differents ways to stay at index 0 after 3 steps.
Right, Left, Stay
Stay, Right, Left
Right, Stay, Left
Stay, Stay, Stay

Example 2:

Input: steps = 2, arrLen = 4
Output: 2
Explanation: There are 2 differents ways to stay at index 0 after 2 steps
Right, Left
Stay, Stay

Example 3:

Input: steps = 4, arrLen = 2
Output: 8

Constraints:

  • 1 <= steps <= 500
  • 1 <= arrLen <= 10^6

Java代码(第6次提交)

我发现最里面的判断执行的次数太多,而且好像可以提出来。

// 执行时间:7ms
class Solution {
    public int numWays(int steps, int arrLen) {
        int mod = 1000000007;
        int[][] dp = new int[501][252];
        dp[0][0] = 1;
        int right = 0;
        for (int i = 1; i <= steps; ++i) {
            right = Math.min(Math.min(i, steps - i), arrLen - 1);
            // 第0列只能加正上方和右上方,左上方出界了
            dp[i][0] = (dp[i - 1][0] + dp[i - 1][1]) % mod;
            for (int j = 1; j <= right; ++j) {// 从1开始
                // 左上方和正上方
                dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j]) % mod;
                dp[i][j] = (dp[i][j] + dp[i - 1][j + 1]) % mod;// 右上方
            }
        }
        return dp[steps][0];
    }
}

Java代码(第5次提交)

// 执行时间:9ms
class Solution {
    public int numWays(int steps, int arrLen) {
        int mod = 1000000007;
        int[][] dp = new int[501][252];
        dp[0][0] = 1;
        int right = 0;
        for (int i = 1; i <= steps; ++i) {
            // 将这里直接用一行表示
            right = Math.min(Math.min(i, steps - i), arrLen - 1);
            for (int j = 0; j <= right; ++j) {
                dp[i][j] = (dp[i][j] + dp[i - 1][j]) % mod;// 两行合为一行
                if (j > 0) {
                    // 两行合为一行
                    dp[i][j] = (dp[i][j] + dp[i - 1][j - 1]) % mod;
                }
                // 两行合为一行
                dp[i][j] = (dp[i][j] + dp[i - 1][j + 1]) % mod;
            }
        }
        return dp[steps][0];
    }
}

Java代码(第4次提交)

// 执行时间:11ms
class Solution {
    public int numWays(int steps, int arrLen) {
        int mod = 1000000007;
        // 第3次太啰嗦,直接固定为最大范围更节省时间,快6ms,
        // 这说明计算比申请内存(这里申请的空间也不大)更耗时
        int[][] dp = new int[501][252];
        dp[0][0] = 1;
        int right = 0;
        for (int i = 1; i <= steps; ++i) {
            right = Math.min(i, steps - i);
            right = Math.min(right, arrLen - 1);
            for (int j = 0; j <= right; ++j) {
                dp[i][j] += dp[i - 1][j];
                dp[i][j] %= mod;
                if (j > 0) {
                    dp[i][j] += dp[i - 1][j - 1];
                    dp[i][j] %= mod;
                }
                dp[i][j] += dp[i - 1][j + 1];
                dp[i][j] %= mod;
            }
        }
        return dp[steps][0];
    }
}

Java代码(第3次提交)

其实步数最多为 500 步,所以最多向右走 250 步,如果继续向右走 1 步,那么就无法回到原点。所以 steps >> 1,又因为需要计算 dp[i][steps >> 1],所以右边还需要 1 位,因此要加 1,又因为这是下标(从 0 开始),所以最终是 (steps >> 1) + 2,但是又不能超过限定的范围。所以就变成了下面写的那样。

// 执行用时:17ms
class Solution {
    public int numWays(int steps, int arrLen) {
        int mod = 1000000007;
        int[][] dp = new int[steps + 1][Math.min((steps >> 1) + 2, arrLen + 1)];// 如此啰嗦
        dp[0][0] = 1;
        int right = 0;
        for (int i = 1; i <= steps; ++i) {
            right = Math.min(i, steps - i);
            right = Math.min(right, arrLen - 1);
            for (int j = 0; j <= right; ++j) {
                dp[i][j] += dp[i - 1][j];
                dp[i][j] %= mod;
                if (j > 0) {
                    dp[i][j] += dp[i - 1][j - 1];
                    dp[i][j] %= mod;
                }
                dp[i][j] += dp[i - 1][j + 1];
                dp[i][j] %= mod;
            }
        }
        return dp[steps][0];
    }
}

Java代码(第2次提交)

第1次提交的时候忘记将输出删掉,,,结果超时了。
第2次提交,内存超出限制。原因是 arrLen 达到 \(10^6\),导致数组过大。

class Solution {
    public int numWays(int steps, int arrLen) {
        int mod = 1000000007;
        int[][] dp = new int[steps + 1][arrLen + 1];// 这里超出内存限制
        dp[0][0] = 1;
        int right = 0;
        for (int i = 1; i <= steps; ++i) {
            right = Math.min(i, steps - i);
            right = Math.min(right, arrLen - 1);
            for (int j = 0; j <= right; ++j) {
                dp[i][j] += dp[i - 1][j];
                dp[i][j] %= mod;
                if (j > 0) {
                    dp[i][j] += dp[i - 1][j - 1];
                    dp[i][j] %= mod;
                }
                dp[i][j] += dp[i - 1][j + 1];
                dp[i][j] %= mod;
            }
        }
        return dp[steps][0];
    }
    // private void print(int[][] dp) {
    //     for (int i = 0; i < dp.length; ++i) {
    //         for (int j = 0; j < dp[i].length; ++j) {
    //             System.out.print(dp[i][j] + " ");
    //         }
    //         System.out.println();
    //     }
    //     System.out.println();
    // }
}

原文链接https://www.cnblogs.com/wowpH/p/11924796.html

- End - wowpH - cnblogs -

LeetCode 5274. Number of Ways to Stay in the Same Place After Some Steps - Java - DP

标签:aced   turn   logs   判断   输出   lan   for   ace   output   

原文地址:https://www.cnblogs.com/wowpH/p/11924796.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!