zoukankan      html  css  js  c++  java
  • 【40讲系列7】贪心算法

    一、理论

    贪心(Greedy)算法:在对问题求解时,总是做出在当前看来是最好的选择。

       由于贪心算法每一次操作都需要取最大值或最小值,所以通常需要对数组排序。

    适用Greedy 的场景:

      问题能够分成子问题来解决,子问题的最优解能递推到最终问题的最优解。 如果不能使用贪心算法,只需要举出反例即可。

    贪心选择性质的证明(利用反证法,证明贪心算法的正确性):

      贪心算法为A,最优算法为O;如果证明过程中发现A完全能替代O,且不影响求出最优解,则出现矛盾。

    贪心算法与动态规划的不同:

    贪心对每个子问题的解决方案都作出选择,不能回退。动态规划则会保存以前的运算结果,并根据以前的结果对当前进行选择,有回退功能。

    二、典型例题

    ①:买卖股票的最佳时期(LC122)

    方法1:贪心(针对此问题的特殊解法,因为一天可以买卖无数次),一次遍历,只要只要后一天比前一天大 就在今天买入然后明天卖出(时间复杂度:O(n))

    class Solution {
        public int maxProfit(int[] prices) {
            int res = 0;
            for (int i = 0; i < prices.length - 1; i++) {
                if (prices[i] < prices[i+1]){
                    res += prices[i+1] - prices[i];
                }
            }
            return res;
        }
    }

     方法2:DP(解决股票问题的通用方法)------(时间复杂度:O(n))

    class Solution {
        public int maxProfit(int[] prices) {
            // 状态的定义:dp[i][j]表示第i天交易完后 持股(j=1)或不持股(j=0)状态下 的最大利润,
            /*
            int n = prices.length;
            int[][] dp = new int[n][2];
            dp[0][0] = 0;
            dp[0][1] = -prices[0];
            for (int i = 1; i < n; i++) {
                dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i]);
                dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] - prices[i]);
            }
            return dp[n - 1][0];
            */
            /**
             *  空间压缩 , 每一天的状态只与前一天的状态有关,
             */
            int n = prices.length;
            int dp0 = 0, dp1 = -prices[0];
            for (int i = 1; i < n; i++) {
                int newDp0 = Math.max(dp0, dp1 + prices[i]);
                int newDp1 = Math.max(dp1, dp0 - prices[i]);
                dp0 = newDp0;
                dp1 = newDp1;
            }
            return dp0;
        }
    }

    三、扩展例题

    第一组:LeetCode455. 分发饼干LeetCode392. 判断子序列

    第二组(贪心算法与动态规划):LeetCode435. 无重叠区间

  • 相关阅读:
    面试笔试题目集
    [vs2010]:fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "StdAfx.h"”?
    [数据库] SQLite常见问题解答
    安卓学习资料总结39
    Android 学习资料总结40
    python变量的定义和使用
    python运算符
    python的注释
    print输出函数
    python数据类型转换
  • 原文地址:https://www.cnblogs.com/HuangYJ/p/14017461.html
Copyright © 2011-2022 走看看