代码随想录算法训练营 动态规划part09

一、买卖股票的最佳时机 

121. 买卖股票的最佳时机 - 力扣(LeetCode)

解题思路
先考虑最简单的「暴力遍历」,即枚举出所有情况,并从中选择最大利润。设数组 prices 的长度为 n ,由于只能先买入后卖出,因此第 1 天买可在未来 n−1 天卖出,第 2 天买可在未来 n−2 天卖出……以此类推,共有 (n−1)+(n−2)+⋯+0=n(n−1)/2 种情况,时间复杂度为 =O(N^2) 。考虑到题目给定的长度范围 1≤prices.length≤10^5,需要思考更优解法。

然而,暴力法会产生许多冗余计算。例如,若第 1 天价格低于第 2 天价格,即第 1 天成本更低,那么我们一定不会选择在第 2 天买入。进一步的,若在前 i 天选择买入,若想达到最高利润,则一定选择价格最低的交易日买入。考虑根据此贪心思想,遍历价格列表 prices 并执行两步:

由于初始值 i=0 ,为了序号对应,本文设从第 0 天开始;

更新前 i 天的最低价格,即最低买入成本 cost;
更新前 i 天的最高利润 profit ,即选择「前 i−1 天最高利润 profit 」和「第 i 天卖出的最高利润 price - cost 」中的最大值 ;

class Solution {
    public int maxProfit(int[] prices) {
        int cost = Integer.MAX_VALUE, profit = 0;
        for (int price : prices) {
            cost = Math.min(cost, price);
            profit = Math.max(profit, price - cost);
        }
        return profit;
    }
}

二、买卖股票的最佳时机II 

122. 买卖股票的最佳时机 II - 力扣(LeetCode)

解题思路
对于单独交易日: 设今天价格 p1 、明天价格 p2,则今天买入、明天卖出可赚取金额 p2−p1(负值代表亏损)。

对于连续上涨交易日: 设此上涨交易日股票价格分别为 p1,p2,...,pn,则第一天买最后一天卖收益最大,即 pn−p1;等价于每天都买卖,即 pn−p1=(p2−p1)+(p3−p2)+...+(pn−p(n−1))。

对于连续下降交易日: 则不买卖收益最大,即不会亏钱。

算法流程:
遍历整个股票交易日价格列表 price,并执行贪心策略:所有上涨交易日都买卖(赚到所有利润),所有下降交易日都不买卖(永不亏钱)。

设 tmp 为第 i-1 日买入与第 i 日卖出赚取的利润,即 tmp = prices[i] - prices[i - 1] ;
当该天利润为正 tmp > 0,则将利润加入总利润 profit;当利润为 0 或为负,则直接跳过;
遍历完成后,返回总利润 profit。

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

你可能感兴趣的:(动态规划,算法)