zoukankan      html  css  js  c++  java
  • Jump Game II

    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
  • 相关阅读:
    搜索文字高亮
    聊天 页面 定位overflow: scroll 原生滚动,iOS下会不流畅,
    MySQL技术专题(X)该换换你的数据库版本了,让我们一同迎接8.0的到来哦!(初探篇)
    Zookeeper原理系列-Paxos协议的原理和Zookeeper中的应用分析
    【Spring技术原理】Aspectj和LoadTimeWeaving的动态代理技术实现指南
    【SpringBoot技术专题】「权限校验专区」Shiro整合JWT授权和认证实现
    👊 Spring技术原理系列-从零开始教你SpringEL表达式使用和功能分析讲解指南(上篇)
    SpringBoot-技术专区-教你如何开发一个”可移植“的轻量级文件服务项目系统!
    ☕【Java技术指南】「JPA编程专题」让你不再对JPA技术中的“持久化型注解”感到陌生了!
    【SpringCloud技术专题】「Eureka源码分析」从源码层面让你认识Eureka工作流程和运作机制(下)
  • 原文地址:https://www.cnblogs.com/neopolitan/p/7780387.html
Copyright © 2011-2022 走看看