码迷,mamicode.com
首页 > 其他好文 > 详细

Jump Game II

时间:2017-11-03 22:03:02      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:mission   bre   一点   技术   大脑   note   element   def   miss   

Date:

  Nov. 3, 2017

Problem:

  https://leetcode.com/problems/jump-game-ii/description/

Description:

  Given an array of non-negative integers, you are initially positioned at the first index of the array.

  Each element in the array represents your maximum jump length at that position.

  Your goal is to reach the last index in the minimum number of jumps.

  For example:

Given array A = [2,3,1,1,4]
The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)

  Note:
  You can assume that you can always reach the last index.

 

  看到题目,我马上想到了一副非常美丽的交错的备忘搜索树的图景,然后意识到wallpaper engine对我大脑的内存占用还是很高的。

  很容易画出example的拓扑图:

技术分享

  每个节点表示数组中的一个位置,节点中有两个值,分别表示位置的索引和到达该位置所需的最小步数。两个节点之间的连线表示可以从索引较小的那个位置走到较大的那个位置。

  于是思维马上开始发散,想到被开水烫变形的动规表,然后就开始想深搜广搜……

  不过既然是一道数组题,我就用粗暴一点的方式来做吧。

  首先设置一个指针pointer,让他指向第0个位置。length,指示最后一个节点的索引。rank,指示pointer遍历至今,我能走到的最远距离。smallest,保存到达每一个走过的位置需要的最小步数。

  接下来,我用指针i遍历pointer + 1, pointer + 2,...,pointer + nums[pointer],即我在pointer这个位置能走过的路径,检查smallest[i]是否存在。这可以通过检查rank与遍历指针的大小关系判断。因为,如果smallest[i]不存在,我们接下来就要把smallest[pointer] + 1加入smallest的末尾,然后让rank += 1,由于遍历指针总是从已经走到的位置开始每次间隔为1地向右移动,所以我们总是不用担心在smallest[233]还未录入时,就录入了smallest[666],同样的,也可以放心地用rank判断接下来的操作到底是录入还是判断替换。

  反之,当我们检查到smallest[i]存在时,我们研究smallest[i]与我们现在走到这个位置的步数smallest[pointer] + 1的大小关系,保留更小的那个数,将其记录在smalles[i]中。

  完成了这一步骤后,我令pointer += 1,继续研究下一个节点和它可以走到的那些节点。如此推演,直到pointer到达length - 1。这时,我将smallest[length]输出。

  这时我想到一个问题。我其实不需要演算rank大于length的部分,万一靠近length的地方有个十个八个的能跳千百万步的,我岂不是死在length门口。因为这一部分计算完全是无用功。所以,我们在指针i遍历的环节加上一个判断条件,仅当i <= length时才进入smallest检查,否则break。

  这好像有点像那啥,戴克斯特拉算法。复杂度为O(N*N)。

  提交,TLE。

  ……

  技术分享

  翻看了一下记录,死在一个[25000, 24999, 24998, ... , 2, 1, 1, 0]。

  这是要搞事吧?

  进一步简化smallest查找。事实上,当一个位置的“步长”覆盖了若干个这样的位置,这些位置的“步长”甚至不能超出这个范围,这时,我们完全没有必要扫描这些位置。

1             if rank >= pointer > 0 and nums[pointer] <= nums[parent[pointer]] - pointer + parent[pointer]:
2                 pointer += 1
3                 continue

  提交,AC。

  这种算法的复杂度是O(N)。(

  以下是submission。

 1 class Solution:
 2     def jump(self, nums):
 3         length = len(nums) - 1
 4         parent = [0]
 5         smallest = [0]
 6         rank = 0
 7         pointer = 0
 8         while pointer < length:
 9             if rank >= pointer > 0 and nums[pointer] <= nums[parent[pointer]] - pointer + parent[pointer]:
10                 pointer += 1
11                 continue
12             for i in range(pointer + 1, pointer + nums[pointer] + 1):
13                 if i <= length:
14                     if rank < i:
15                         rank += 1
16                         smallest.append(smallest[pointer] + 1)
17                         parent.append(pointer)
18                     elif smallest[i] > smallest[pointer] + 1:
19                         smallest[i] = smallest[pointer] + 1
20                         parent[i] = pointer
21                 else:
22                     break
23             pointer += 1
24         return smallest[length]

  jianchao.li.fighter优美的BFS算法,step全局记录,复杂度O(N)。

 1 class Solution:
 2     def jump(self, nums):
 3         n, start, end, step = len(nums), 0, 0, 0
 4         while end < n - 1:
 5             step += 1
 6             maxend = end + 1
 7             for i in range(start, end + 1):
 8                 if i + nums[i] >= n - 1:
 9                     return step
10                 maxend = max(maxend, i + nums[i])
11             start, end = end + 1, maxend
12         return step

 

Jump Game II

标签:mission   bre   一点   技术   大脑   note   element   def   miss   

原文地址:http://www.cnblogs.com/neopolitan/p/7780387.html

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