贪心Greedy
来源:互联网 发布:手机维修店刷机软件 编辑:程序博客网 时间:2024/05/26 08:41
先看一下这个问题:
LeetCode 55. Jump Game
Question
如果从某个索引位置能到达最后一个索引,那我们就称这个位置为 "good index",否则,称为"bad index".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.
Determine if you are able to reach the last index.
For example:
A =[2,3,1,1,4]
, returntrue
.A =
[3,2,1,0,4]
, returnfalse
.
这是一个动态规划问题,通常解决动态规划问题的思路如下:
1.考虑递归回溯方法(recursive backtracking solution)
2.利用存储表来进行优化的递归方法(top-down 自上而下的动态规划)
3.不使用递归(bottom-up自底向上的动态规划)
4.final tricks to reduce thi time/ memory complexity
Approach #1 (Backtracking) [Stack Overflow]
这是一种低效方法,从first positon开始,跳到每一种可能到达的位置。重复这个过程,直到到达最后的位置。如果中途中断,则backtrack。在此基础上的优化是:在每次判断下一个位置是否能够到达时,先判断它的最远到达位置,如果能到的最远的那个位置是可以到达 的,就不用再判断前面的了。这样可以在实际情况中减少很多次判断的可能。如果远的地方的不行,在一点点往回减1,进行下一轮的判断。
时间复杂度O(2^n)
空间复杂度O(n)
Approach #2 (Dynamic Programming Top-down) [Stack Overflow]
Top-down Dynamic Programming 自顶向下的动态规划可以被看作是回溯方法的优化。依赖于某个位置一旦被认定为good or bad Index这个结果就不会再发生任何变化。这意味着我们可以将这个结果保存下来而不用每次用到时都去多次计算。这种方法被称作memorization。
定义一个memo数组,数组中的值为:GOOD、BAD、UNKNOWN。
例如对于数组
nums = [2, 4, 2, 1, 0, 2, 0]
对应的存储数组为:Approach #3 (Dynamic Programming Bottom-up) [Time limit exceeded]
不使用递归的方法。对内存的使用更优化,因为不用使用每次递归时的方法栈。
自底向下的方法是从数组的最后一位开始对memo数组赋值,这样每次对左边的下一次的memo数组赋值时,只需要通过查找右边的memo数组即可。
Java实现:
enum Index { GOOD, BAD, UNKNOWN}public class Solution { public boolean canJump(int[] nums) { Index[] memo = new Index[nums.length]; for (int i = 0; i < memo.length; i++) { memo[i] = Index.UNKNOWN; } memo[memo.length - 1] = Index.GOOD; for (int i = nums.length - 2; i >= 0; i--) { int furthestJump = Math.min(i + nums[i], nums.length - 1); for (int j = i + 1; j <= furthestJump; j++) { if (memo[j] == Index.GOOD) { memo[i] = Index.GOOD; break; } } } return memo[0] == Index.GOOD; }}
时间复杂度O(n^2)
空间复杂度O(n)
Approach #4 (Greedy) [Accepted]
贪心方法:
在有了bottom-up方法后,我们很容易观察到:对于一个给定的位置,当我们判断是否能够跳到good position时,是从给定位置的下一个位置从左一步一步的向右一点点判断的。
从右向左迭代,判断当前位置+能跳的最大步数是否大于或等于离她最近的good Index,即判断:
currPosition + nums[currPosition] >= leftmostGoodIndex
要是能到最近的good position,就说明当前位置是good .然后更新离的最近的good position的位置,也就是leftmostGoodIndex.迭代直到到达数组的首位。
时间复杂度O(n)
空间复杂度O(1)
public class Solution { public boolean canJump(int[] nums) { int leftmostGoodIndex=nums.length-1; for(int j=nums.length-2;j>=0;j--){ if(j+nums[j]>=leftmostGoodIndex){ leftmostGoodIndex=j; } } return leftmostGoodIndex==0; }}
1 0
- 贪心Greedy
- HDU4221(Greedy?)贪心
- 贪心算法(Greedy Algorithms)
- hdu4221 Greedy?(贪心)
- 贪心--HDU - 4221 Greedy?
- hdu Greedy 4221 (贪心)
- HDU 4221 Greedy?(贪心)
- 贪心算法(Greedy algorithm)
- 贪心算法(greedy algorithm)
- HDU 4221 Greedy?(贪心)
- hdu 4221 Greedy 贪心算法
- HDU 4221 Greedy?(贪心)
- nyoj 824 Greedy Mouse【贪心】
- 贪心算法(greedy algorithm)
- 贪心区间调度 Greedy interval scheduling problem
- 贪心算法也挺好-Greedy is Good
- 1.1.2 Greedy Gift Givers【贪心】
- 贪心算法(GREEDY ALGORITHM)证明实践
- 数位dp+矩阵乘法 【bzoj3329】Xorequ
- Epoll详解及源码分析
- ASP.NET中 CompareValidator(比较验证)的使用
- 使用 Servlet 作为控制器,标准MVC模式
- 【Go语言】连接数据库SQLite、MySQL、Oracle
- 贪心Greedy
- rs.getTimestamp和pstmt.setTimestamp
- eclipse创建Hibernate Demo中需要注意的地方
- (转)SQLite3 多线程访问
- 4-18 递归求Fabonacci数列 (10分)
- java.sql.SQLException: 无效的列类型: 1111
- French Word
- 插件介绍:轻量级表格树treegrid, 支持bootstrap 风格
- Python学习笔记11_IO编程