1. 简介
贪心算法在对问题进行求解时,总是做出在当前看来最好的选择,即不从整体最优上加以考虑,而是进行某种意义上的局部最优解。一般将求解过程分成若干个步骤,但每个步骤都应用贪心原则,选取当前状态下最好/最优的选择(局部最有利的选择),并以此希望最后堆叠出的结果也是最好/最优的解
- 算法流程:
(1)从某个初始解出发;
(2)进行迭代,当目标向前进一步时,根据局部最优策略,得到部分解,缩小问题规模;
(3)综合所有局部最优解得到最优解; - 适用范围:
贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。
2、基本要素
- 贪心选择:
贪心选择是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。贪心选择是采用从顶向下、以迭代的方法做出相继选择,每做一次贪心选择就将所求问题简化为一个规模更小的子问题。 - 最优子结构:
当一个问题的最优解包含其子问题的最优解时,称该问题具有最优子结构。问题的最优子结构性质是该问题可用贪心算法或动态规划算法求解的关键特征。
3、例题
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 1:
输入: [2,3,1,1,4]
输出: true
解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/jump-game
/**
分析:
1.确定初始位置和能跳到的最远位置rightmost;
2.跳到下一个位置,判断是否超过最远位置,若超过,返回false,
若未超过,更新可以到达的最远位置(比较rightmost和i+nums[i]的大小);
3.重复2过程,直至到达末尾位置,返回true;
*/
public class Solution {
public boolean canJump(int[] nums){
//可以跳的最远位置
int rightmost = 0;
for(int i =0;i < nums.length;i++){
if(i>rightmost) return false;
rightmost = Math.max(rightmost,i+nums[i]);
}
return true;
}
}
4、贪心算法和动态规划区别
- 贪心算法考虑的是局部最优解,动态规划考虑的是全局最优解。
- 贪心算法的每一次操作都对结果产生直接影响,而动态规划则不是。
- 贪心算法对每个子问题的解决方案都做出选择,不能回退;动态规划则会根据以前的选择结果对当前进行选择,有回退功能。
- 动态规划主要运用于二维或三维问题,而贪心一般是一维问题。