zoukankan      html  css  js  c++  java
  • 五大算法之贪心算法

            贪心算法是指对子问题取最值,从而求得局部最优解,并以此求得全局最优解。贪心算法可以认为是动态规划的一个特例,同样是需要将问题分解为子问题,避免了子问题的重复计算,只不过在子问题的处理上贪心算法更加简单直接。贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。

            举个简单的例子,有10、5、3面额的钞票各若干张,现在规定只能拿10张,问最多能拿多少钱。显然每次都拿剩下钞票中最大的面额,最后能取得最优解。但是如果换成凑够某金额最少的钞票数,那么贪心算法没办法得到最优解,因为每次取最大面额,最后可能出现面额不合适,从而使用大量小面额凑零,反而增加了钞票数,面对这种问题,贪心策略就不具备无后效性。

            以上介绍了贪心算法的概念及局限性,对于符合贪心策略的问题,基本思路如下:

    • 建立数学模型来描述问题;
    • 分成若干个子问题;
    • 求解子问题的局部最优解;
    • 将局部最优解合成最终解。

            能够满足贪心算法使用条件的问题实际上很少,所以在使用贪心算法前一定要验证问题是否满足贪心算法的条件。那么对于相关的例题,大家喜欢上来就一道0-1背包,然后一顿分析贪心算法在此问题上的不成立,可以说很不给贪心算法的面子,下面就以跳跃游戏问题为例,让贪心算法成立一次。

    跳跃游戏(LeetCode-55)

              我们把此类为题转变为最值问题,即跳跃最远距离覆盖最后一个位置认为能够达到最后一个位置。那么求最远跳跃距离可以分解为求每一步跳跃的最远距离,贪心算法具体思路如下:

    bool canJump(vector<int>& nums) {
        int n = nums.size();
        int farthest = 0;
        for (int i = 0; i < n - 1; i++) {
            // 不断计算能跳到的最远距离
            farthest = max(farthest, i + nums[i]);
            // 可能碰到了 0,卡住跳不动了
            if (farthest <= i) return false;
        }
        return farthest >= n - 1;
    }

            每一步都计算一下从当前位置最远能够跳到哪里,然后和一个全局最优的最远位置farthest做对比,通过每一步的最优解,更新全局最优解。相对于动态规划,贪心算法的优势在于,时间复杂度为O(N),空间复杂度为O(1),但是使用时必须满足贪心算法的条件。

    跳跃游戏 ΙΙ(LeetCode-45)

            下面再将问题升级为求最少跳跃次数,同样可使用贪心算法解决。

              解题思路为:每一步必须跳,那么就求出每一步能够跳的最远距离,即将原问题分解为每一步跳跃使得后续的可跳距离最远。如下图所示,位置0最大可跳2个位置,具体跳到位置1还是位置2呢?由于位置1可跳范围比位置2更远,所以在位置0选择跳到位置1,之后每一步都按照同样的策略取下一跳位置。

      代码如下:

    int jump(vector<int>& nums) {
        if(nums.size()<=1) return 0;
        int step=0, start=0,reach=0;
        while( reach <nums.size()-1 ){
            int farest=0;
            // 遍历可跳范围,取可跳最远的位置作为下一跳
            for(int i=start; i<=reach; i++)
                farest=max(farest,i+nums[i]);
            start=reach+1;
            reach=farest;
            step++;
        }
        return step;
    }
  • 相关阅读:
    从零开始写代码AdaBoost算法的python实现
    从零开始写代码 ID3决策树Python
    redis有启动,但是其他主机telnet 不通的问题
    关于js查找和筛选和循环的几种方式(find();findIndex();filter();some();every();forEach;map();for/in)
    linux 设置tomcat 重启清空 catalina.out 断舍离
    旋转数组 断舍离
    nginx 普通用户启动配置 && springbootswagger 报错 Unable to infer base url 断舍离
    CentOS yum 直接安装最新的nginx【转】 断舍离
    买卖股票的最佳时机 II 断舍离
    swagger 的 pathmapping 配置的理解 断舍离
  • 原文地址:https://www.cnblogs.com/BobPong/p/13053180.html
Copyright © 2011-2022 走看看