-1269. 停在原地的方案数

题目描述

有一个长度为 arrLen 的数组,开始有一个指针在索引 0 处。

每一步操作中,你可以将指针向左或向右移动 1 步,或者停在原地(指针不能被移动到数组范围外)。

给你两个整数 steps 和 arrLen ,请你计算并返回:在恰好执行 steps 次操作以后,指针仍然指向索引 0 处的方案数。

由于答案可能会很大,请返回方案数 模 10^9 + 7 后的结果。

样例

示例 1:
输入:steps = 3, arrLen = 2
输出:4
解释:3 步后,总共有 4 种不同的方法可以停在索引 0 处。
向右,向左,不动
不动,向右,向左
向右,不动,向左
不动,不动,不动

示例 2:
输入:steps = 2, arrLen = 4
输出:2

示例 3:
输入:steps = 4, arrLen = 2
输出:8

注意:
1 <= steps <= 500
1 <= arrLen <= 10^6

思路

  • 这个题目一眼望去动态规划~
  • 创建一个二维数组dp,其中dp[ i ] [ j ] 表示第 i 步处于位置 j 的方案总数。
    非常容易发现状态转移公式为:dp[ i ] [ j ] = dp[ i -1] [ j-1 ] + dp[ i -1] [ j ] + dp[ i-1 ] [ j+1 ],以及边界条件dp[ 0 ] [ 0 ] = 1
  • 但是按照上面的说法建数组,内存开销太大了,因为数组的第二维arrLen是10^6数量级。注意到,我们要求进行steps步操作后,位于0位置的,对于位置下标大于steps的,就算每一步让它往左移动,都无法在最后到达0位置,所以过大的下标位置不用考虑。设置dp数组的第二维为最大下标为 min (steps , arrLen-1 )。
  • 然后按照上面说的迭代求解,最后返回 dp[steps][0]即可~
  • 注意到在第 i 步时,我们只用到了第 i-1步的结果,所以空间复杂度可以进一步压缩。只用两个一维数组 dp 和 newDp即可实现上面的操作~
  • 时间复杂度为 O( steps×min(arrLen,steps) )
  • 空间复杂度为 O(min(arrLen,steps))

代码

class Solution {
    public int numWays(int steps, int arrLen) {
    	int MM = 1000000007;
    	int len = Math.min(steps, arrLen-1);
    	int []dp = new int [len+1];
    	dp[0] = 1;
    	for(int i = 1;i <= steps;i++) {
    		int []newDp = new int [len+1];
    		for(int j = 0;j <= len;j++) {
    			newDp[j] = dp[j];
    			if(j > 0)
    				newDp[j] = (newDp[j] + dp[j-1])%MM;
    			if(j < len)
    				newDp[j] = (newDp[j] + dp[j+1])%MM;
    		}
    		dp = newDp;
    	}
    	return dp[0];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值