美文网首页
44. Jump Game II

44. Jump Game II

作者: sarto | 来源:发表于2022-03-30 19:07 被阅读0次

题目

给定一个非负数组 nums,你一开始在数组的第一个索引。
数组中的每个元素表示你在该位置可以跳的最大距离。
你的目标是以最少的跳跃次数,到达最后一个索引。
你可以认为你总能到达最后一个索引。

解析

这个问题看起来就像是一个动态规划的问题。
f(n) = canjump(n-i) + f(n-i)

  1. 假设跳转的目标索引是 target
  2. 在 target 之后找到一个数字 jump
  3. 如果这个数字能跳转到 jump,那么到达 target 所需的次数是后边的数到达 jump 的次数 + 1。
  4. 如果这个数字不能到达 target,放弃这次循环。

伪代码

jump(nums []int, target, j)

if nums[j] < target-i 
    return MAX
for i:=len(num)-1;i--
  if nums[i] >= target-i
    min = f(num[:i]) + 1
    if min < rst
      rst = min
return min

上边的代码效率会太慢,因为会重复计算位置,考虑循环解决这个问题。

  1. 计算 f(0) 得到 f(0) = 0
  2. 计算 f(1),f(1) = f(0) + 1 条件:num[0] 一定大于 0
  3. 计算 f(2),f(2)= min(f(0) + 1 f(1) + 1)
  4. 计算 f(3), f(3) =min(f(0)+1, f(1)+1, f(2)+1)
f map[int]int
for target := 1; target<len(nums);target++
  min = MAX
  for i:=0;i<target;i++
    if nums[i] > target-i
        min = min(min, f[i]+1)
  f[target]=min

代码

func jump(nums []int) int {
    f := map[int]int{0:0}
    for target:=1; target<len(nums); target++ {
        rst := 1<<31-1
        for i:=0;i<target;i++{
            if nums[i] >= target-i {
                rst = min(rst, f[i]+1)
            }
        }
        f[target]=rst
    }
    return f[len(nums)-1]
}

func min(a,b int) int {
    if a < b {
        return a
    }
    return b
}
image.png

map 改为 slice。内存利用率和查询速度都有所提升。

image.png

算法改进。

  1. 问题在于,第二次迭代的时候,每次都是从 0 到 n 比较计算。其实这个时候,已经有一些元素无法再到达这个地址了。对于这些元素,我们要将其抛弃掉。不再计算和比较。
  2. 我们需要一个map结构,因为 map 结构,有界,可删除。 map[address][]index,key 表示目标地址,值是可以到达这些目标地址的索引。
  3. 当我们走到一个 address 地址时,我们在 map 中删除 address-1,然后遍历 map,得到索引值,比较并计算。
f map[int]int
addr map[int][]int
f[0] = 0
addr[nums[0]] = []int{0}
for target := 1; target<len(nums);target++
  delete(addr, target-1)
  min = MAX
  for _, v := range addr
    for _,i = range v
        min = min(min, f[i]+1)
  f[target]=min
  addr[nums[target]] = []int{target}

代码

func jump(nums []int) int {
    f := make([]int,len(nums))
    addr := map[int][]int{}
    f[0] = 0
    addr[nums[0]] = append(addr[nums[0]], 0)
    for target:=1; target<len(nums); target++ {
        delete(addr, target-1)
        rst := 1<<63-1
        for _,idxs := range addr {
            for _, idx := range idxs {
                rst = min(rst, f[idx]+1)
            }
        }
        f[target]=rst
        addr[nums[target]+target] = append(addr[nums[target]+target], target)
    }
    return f[len(nums)-1]
}

func min(a,b int) int {
    if a < b {
        return a
    }
    return b
}
image.png

并没有预期的效率提升?

相关文章

  • 44. Jump Game II

    题目 给定一个非负数组 nums,你一开始在数组的第一个索引。数组中的每个元素表示你在该位置可以跳的最大距离。你的...

  • 坐标型--(b)跳格子

    1) jump game I, II (LeetCode 55, 45) [ 要求] 给出jump power数组...

  • 44. Jump Game II 跳跃游戏II

    做完 Jump Game,再来看看这个题目。 题目 给定一个非负数组 nums,你一开始在数组的第一个索引。数组中...

  • [DP]45. Jump Game II

    前篇 55. Jump Game 45. Jump Game II 感谢Jason_Yuan大神优秀的解析:链接 ...

  • 45. Jump Game II

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

  • Leetcode-45Jump Game II

    45. Jump Game II Given an array of non-negative integers,...

  • dp

    10 Regular Expression Matching 45. Jump Game II 62 Unique...

  • 【贪心】45.Jump Game II

    题目链接 https://leetcode.com/problems/jump-game-ii/descripti...

  • 【LeetCode】45. 跳跃游戏 II

    链接:https://leetcode-cn.com/problems/jump-game-ii/descript...

  • Jump Game II

    题目:Given an array of non-negative integers, you are initi...

网友评论

      本文标题:44. Jump Game II

      本文链接:https://www.haomeiwen.com/subject/glyijrtx.html