LeetCode 👉 HOT 100 👉 买卖股票的最佳时机 - 简单题

106 阅读3分钟

「这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战」。

题目

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0

示例1

输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

示例2

输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 没有交易完成, 所以最大利润为 0。

思路

按照炒股票的套路,是低价买入、高价卖出就能赚钱。比如 3入,5卖 能赚钱,6入,8卖 也能赚钱,就意味着可以反复操作。但是注意题目的要求,某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票,就意味着只能操作一次,那就是要求 prices 中,后者比前者大的最大差值。

简单一点,暴力解法,枚举数组中的每一项为买入点,同时枚举该项之后的每一项为卖出点,计算收益,每次保留收益最大值

暴力解法

    /**
     * @param {number[]} prices
     * @return {number}
     */
    var maxProfit = function(prices) {
        let max = 0, n = prices.length;

        for(let i = 0; i < n; i++) {
            for(let j = i + 1; j < n; j++) {
                const cur = prices[j] - prices[i];
                if(cur > max) {
                    max = cur;
                }
            }
        }

        return max;
    };

暴力解法的时间复杂度为 O(n ^ 2),随着 n 的增加,时间复杂度呈指数级增加

思考: 能不能用一次循环解决这个问题?可以!

如果只能交易一次,我们再维护一个变量 minPrice,表示当前的最低价,每次枚举时,如果当前价格比 minPrice 低,则更新 minPrice,否则判断当前卖出的话,能赚多少钱,同时判断这个收益和最大收益比较取大值,当枚举完成后,max 即是最大收益。

一次遍历解法

    
    /**
     * @param {number[]} prices
     * @return {number}
     */
    var maxProfit = function(prices) {
        let max = 0, n = prices.length, minPrice = Number.MAX_VALUE;

        for(let i = 0; i < n; i++) {
            // 更新最小价格
            if(prices[i] < minPrice) {
                minPrice = prices[i];
            } else if(max < prices[i] - minPrice) {
                // 更新最大收益
                max = prices[i] - minPrice
            }
        }

        return max;
    };

小结

以后如果知道了股票的价格我肯定不这么操作!多操作几次不是更香么 😄

LeetCode 👉 HOT 100 👉 买卖股票的最佳时机 - 简单题

合集:LeetCode 👉 HOT 100,有空就会更新,大家多多支持,点个赞👍

如果大家有好的解法,或者发现本文理解不对的地方,欢迎留言评论 😄