LeetCode 55 - 跳跃游戏 - 解题思路记录(动态规划优化版) - GoLang

822 阅读4分钟

Hello, 大家好,我又来分享算法题目了, 细心的朋友们应该可以看到这一次的画面更加美观了
没错, 就是因为以前的做法感觉太随便了,而且不够美观 对于一个程序员怎么可以那么没有要求呢?

顺便附带上GitHub的代码地址:LeetCode代码集合-持续更新中

我们来回忆一下,昨天晚上的例子

如果你没看这一一篇的话, 记得要去观看来张飞机票LeetCode 55 - 跳跃游戏 - 解题思路记录(递归+动态规划法) - Golang

这一节课讲的主要是, 递归以及动态规划的例子, 那么很明显的问题就是...效率极低 那么我们也没有什么思路可以让效率更高一些呢?

那么今天就来讲解另外2种思路
1. 动态规划
2. 优化版动态规划(优化的是空间复杂度)
那我们就顺着这个思路往下走, 先来了解一下动态规划的算法去取代掉递归的算法

动态规划版

大家应该忘记,我们动态规划是需要一个表来存储以往的记录的吧,在这个算法里, 我们照样需要使用到这个数组

那么这个做法就是不使用递归, 用for循环做, 我们继续看代码

func nonRecurrentJump(nums[] int, dp *[]int) bool{
 for i:= len(nums)-2;i>=0;i-- {
  maxJump := min(i+nums[i], len(nums)-1) //获取跳跃的步数
  for j := i + 1; j<=maxJump; j++{
   if (*dp)[j] == 1{
    (*dp)[i] = 1
    break
   }
  }
 }
 if (*dp)[0] == 1{
  return true
 }
 return false
}

在这个算法中, 跟递归的很像,唯一的差别就是在于在第二个For的循环中,我们不在是进入递归了, 而是直接查看
dp[j]==1是否成立, 而这段代码中我们的思路其实转变了, 递归的思想是从头开始找, 而这段代码是从后往前

我们把问题简化一下, 从需要到达dp[len(nums)-1] 变成 dp[len(nums)-i]
因为只要我们能到达 2 这个元素,说明我们可以达到终点, 那么从2往前的元素,只需要知道自己能不能到达2

这就是这个算法的核心所在, 如果可以到达 则把 dp[i]=1 并且跳出内层循环,直到最后的结果应该是这样

中间的 1 和 0 是不会被赋值的, 因为它们无法到达 2

最后, 我们判断 dp[0]==1 是否成立,如果成立代表从第0个出发,可以到达终点, 很明显我们比起递归而言要快将近5倍的时间

优化动态规划

我们在想深一层次, 我们真的需要这个数组吗?

其实不需要对吧, 为什么? 因为我们一直都是在与 最新 的一个元素做对比, 那我们为什么还需要一个数组去存储呢?
这个的优化思路跟它LeetCode 53 - 最大子序和 - 解题思路记录(附带动态规划) - GoLang很像
也就是说,我们可以去掉数组,将代码简化成这样...

func optimizeNonRecurrentJump(nums[] int) bool{
	aim := len(nums)-1 //终点
	for i:= len(nums)-2;i>=0;i-- {
		maxJump := min(i+nums[i], len(nums)-1)
		for j := i + 1; j<=maxJump; j++{
			if j == aim{
				aim = i //更新最近的终点
			}
		}
	}
	if aim == 0{
		return true
	}
	return false
}

新建 一个变量叫aim 永远拿它指向最后一个终点, 如果有比它更前的元素接近终点, 则更新它
最后我们判断 aim==0 是否成立,就知道我们第一个元素是否可以到达终点拉

这个方案比之前的省下了0.2MB的空间 又一次的进步。

创作不易, 希望留下你们的小赞赞,是最大的鼓励

其他相关题目连接

LeetCode 55 - 跳跃游戏 - 解题思路记录(递归+动态规划法) - Golang

LeetCode 53 - 最大子序和 - 解题思路记录(附带动态规划) - GoLang

LeetCode 49 - 字母异位词分组 - 解题思路记录 - Golang

LeetCode 21 - 合并有序链表 - 解题思路记录 - GoLang

LeetCode 2 - 两数之和 - 解题思路记录 - GoLang

LeetCode 12 - 罗马数字 - 解题思路记录 - GoLang

LeetCode 15 - 3数之和 - 解题思路记录 - GoLang

LeetCode 5 - 回文串 - 解题思路记录 - GoLang

LeetCode代码集合-持续更新中