JAVA程序设计:LCP 09. 最小跳跃次数(2020 力扣杯!Code Your Future 春季全国编程大赛 )

为了给刷题的同学一些奖励,力扣团队引入了一个弹簧游戏机。游戏机由 N 个特殊弹簧排成一排,编号为 0 到 N-1。初始有一个小球在编号 0 的弹簧处。若小球在编号为 i 的弹簧处,通过按动弹簧,可以选择把小球向右弹射 jump[i] 的距离,或者向左弹射到任意左侧弹簧的位置。也就是说,在编号为 i 弹簧处按动弹簧,小球可以弹向 0 到 i-1 中任意弹簧或者 i+jump[i] 的弹簧(若 i+jump[i]>=N ,则表示小球弹出了机器)。小球位于编号 0 处的弹簧时不能再向左弹。

为了获得奖励,你需要将小球弹出机器。请求出最少需要按动多少次弹簧,可以将小球从编号 0 弹簧弹出整个机器,即向右越过编号 N-1 的弹簧。

示例 1:

输入:jump = [2, 5, 1, 1, 1, 1]

输出:3

解释:小 Z 最少需要按动 3 次弹簧,小球依次到达的顺序为 0 -> 2 -> 1 -> 6,最终小球弹出了机器。

限制:

1 <= jump.length <= 10^6
1 <= jump[i] <= 10000

思路:比赛时采用的BFS,下来后发现榜单前几名几个大佬的做法,学到了很多,下面对着某位大佬的思路改写了自己的方法。大致思路是一样的。

该题完全可以通过模拟整个跳跃过程,对于当前位置i我们下步的选择无非是走到i+jump[i],或者跳到i左边任意一个位置上,一个简单的思路就是通过BFS来枚举下步的状态,通过保存每次所能跳的最远点使得优化状态的遍历。这个解法相信比赛中大多数人都可以想得到的。我们要知道下一步要走的点一定是之前没走过的点,因为若下个点走过,说明我通过更优的方法已经走到了呢个点,完全没必要再绕远路过去,因此我们可以模拟每次走的点,并按顺序加入队列中,最终通过遍历所有状态找到最优解(第一次跳出去所使用的步骤一定是最小步骤)。

class Solution {
    public int minJump(int[] jump) {
    	
    	int i=0;
    	int n=jump.length,head=0;
    	int[] d=new int[n];
    	int[] q=new int[n];
    	Arrays.fill(d, -1);
    	int l=0,r=0;
    	d[0]=0; q[r++]=0;
    	while(l!=r) {
    		i=q[l++];
    		if(i+jump[i]>=n) break;
    		if(d[i+jump[i]]==-1)
    			d[q[r++]=i+jump[i]]=d[i]+1;
    		for(;head<i;head++)
    			if(d[head]==-1)
    				d[q[r++]=head]=d[i]+1;
    	}
    	
    	return d[i]+1;
    }
}	
扫描二维码关注公众号,回复: 11154651 查看本文章
原创文章 1111 获赞 194 访问量 25万+

猜你喜欢

转载自blog.csdn.net/haut_ykc/article/details/105603936
今日推荐