题目描述
台阶一共有n层,有一些台阶上有积水。
牛牛一开始在第0层,它每次可以跳奇数层台阶,他想跳到第n层,但是它不希望在跳跃的过程中踩到积水。
已知有m个台阶上有积水。
请问牛牛在不踩到积水的情况下跳到第n层有多少种不同的方案。如果不可能到达第n层,则答案为0。
为了防止答案过大,答案对1e9+7取模。
方法一:递归求解
求解思路
对于本题目的求解,由于当前层的方案数和前一层有关,因此我们想到使用递归的方法进行求解,根据上述思想,我们即可得到本问题的解答。递归公式如下图展示。
解题代码
import java.util.*;
public class Solution {
int[] memory;
boolean[] w; // 存储积水的位置
public int solve (int n, int m, int[] a) {
memory=new int[n+1]; // 初始化数组
w=new boolean[n+1];
Arrays.fill(memory,-1);
for(int i=0;i<m;i++)
{
w[a[i]]=true;
}
return dfs(n,m,a);
}
private int dfs(int n, int m, int[] a)
{
if(memory[n]!=-1) return memory[n];
if(w[n])
{
memory[n]=0; // 这个地方有积水
return 0;
}
if(n==0||n==1) return 1;
int count=0; // 存储方案数
for(int i=1;i<=n;i+=2)
{
count=(count+dfs(n-i,m,a))%1000000007; // 更新结果
}
memory[n]=count;
return count; // 返回方案数
}
}复杂度分析
时间复杂度:n次递归,并且每次递归的时间复杂度为,因此时间复杂度为
(
)
空间复杂度:使用memory[n],因此空间复杂度为
方法二:迭代思想求解
求解思路
对于本题目的求解,我们可以将积水分为在奇数层和偶数层来分别讨论。在进行方案累加过程中,如果当前层有积水,则跳过当前层。如果没有积水则进行方案的累加。同时对奇数层和偶数层分别进行讨论,这样根据上述思路即可得到本问题的答案。
解题代码
import java.util.*;
public class Solution {
public int solve (int n, int m, int[] a)
{
//odd为之前层的奇数层方案累加和,even为之前层的偶数层方案累加和
int onum=0,evnum=1,id=0;
for(int i=1;i<=n;i++)
{
if(id<m&&a[id]==i)
{ //积水层,跳过
id++;
continue;
}
if(i%2==1)
{ // case odd
onum=(onum+evnum)%1000000007;
}
else
{ // case even
evnum=(evnum+onum)%1000000007;
}
}
for(int w:a)
{
if(w==n) return 0;
}
return n%2==1?evnum:onum; // 返回结果
}
}复杂度分析
时间复杂度:一层循环,因此时间复杂度为
空间复杂度:常数级内存空间,因此空间复杂度为

京公网安备 11010502036488号