leetcode[55]跳跃游戏

题目就是这么个题目,难也不是一般的难,考察的是动态规划和贪心算法

本文我将从三种方法来编码解决这道题(动态规划(topdown)、动态规划(downup)、贪心)

一、动态规划(topdown从开始到结尾)

递归的过程,把所有的可能展开;探索所有的路是否能走通,将结果往下压

那么如何将动态规划加入递归里呢?

假设:3不是开始位置,3前面还有以一些数据,但是,一旦我们认定了1是一条思路之后,我们可以认为:只要从前面的地方(不管是从哪个地方)只要到了1,那么就不用继续往下走了,这条路肯定是不同的,直接返回即可。

首先,我们需要建立一个表格

 

小二迫不及待地为大家上了代码

var canJump = function (nums) {
  // 记录数组的总长度
  const totalLength = nums.length - 1
  // 初始化一个记忆数组,填充为0
  const memo = Array(totalLength).fill(0)
  // 最后一位为1
  memo[totalLength - 1] = 1

  // 递归函数,传递一个位置
  function jump(position){
    // 看当前的位置是否是通路(1通,-1不通,0未知)
    if(memo[position] === 1){
      return true
    }else if(memo[position] === -1){
      return false
    }

    // 定义一个变量maxJump用来存放跳跃步数(防止越界)
    const maxJump = Math.min(position + nums[position],totalLength -1)
    // 遍历所有的步数
    for(let i = position +1;i<=maxJump;i++){
      const jumpResult = jump(i)
      // 如果是true,证明:此位置是通的,将true往上传
      if(jumpResult === true){
        memo[position] =1
        return true
      }
    }
    // 如果所有的路都尝试了,仍没有返回true,就将此位置置为-1(不通),
    // 将false往上传
    memo[position] = -1
    return false
  }

  let result = jump(0)
  return result
};

二、动态规划(downup从结尾到开始)

// 动态规划(downup)
var canJump = function (nums) {
  // 记录数组的总长度
  const totalLength = nums.length 
  // 初始化一个记忆数组,填充为0
  const memo = Array(totalLength).fill(0)
  // 最后一位为1
  memo[totalLength - 1] = 1

  // 从倒数第二位开始向前遍历(倒数第一位已经是1)
  for(let i = totalLength - 2; i>=0; i--){
    const maxJump = Math.min(i+nums[i],totalLength -1)
    // 遍历可走的步数
    for(let j = i+1;j <= maxJump;j++){
      // 只要有某个步数可以到1,剩下的就不用看了直接break返回
      if(memo[j] === 1){
        memo[i] = 1
        break
      }
    }
  }
  // 如果顺利的遍历到了第一位,且为1,就代表成功了
  if(memo[0] === 1){
    return true
  }else{
    return false
  }
};

三、贪心算法

 * 1.定义一个变量maxJump,等于数组的长度-1
 * 2.从后往前遍历,判断前一位的值+索引的和是否大于等于maxJump
 * 如果大于等于的话说明前一位一定能走到后面一位
 * 3.大于等于情况下:maxjump变为前一位的索引
 * 4.如果小于的话,就放弃前一位,继续往前
 * 5.for循环遍历完成之后,判断maxjump是否等于0,
 * 等于的话返回true,否则返回false
 * [3,1,0,2,4]计算过程
 *  0,1,2,3,4
 * 第一步:maxjump = 4
 * 第二步:2+3=5 >= 4,maxjump = 3
 * 第三步:0+2=2 <3 ,继续往前
 * 第四步:1+1=2 <3,继续往前
 * 第五步: 3+0=3 >=3,maxjump =0,返回true
var canJump = function(nums) {
  let maxJump = nums.length-1
  for(let i = nums.length-2;i>=0;i--){
    if(nums[i]+i >= maxJump){
      maxJump = i
    }
  }
  return maxJump === 0
};

  

posted @ 2020-05-13 14:58  天空003  阅读(211)  评论(5编辑  收藏  举报