《leetcode121. 买卖股票的最佳时机》

222 阅读2分钟

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润。

注意:你不能在买入股票前卖出股票。

  示例 1:

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

示例 2:

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

解法一:暴力求解

双重循环,外层循环i表示在i天买入,内层循环j表示在j处卖掉。因为必须先买后卖,所以j始终在i后边。暴力枚举出所有情况,对于每种情况,保存利润最大值,即j-i的差值

var maxProfit = function(prices) {
    let max=0
    for(let i=0;i<prices.length-1;i++){
        for(let j=i+1;j<prices.length;j++){
            if(prices[j]>prices[i]){
                max=Math.max(max,prices[j]-prices[i])
            }
        }
    }
    return max
};

时间复杂度O(n2)

解法二:一次遍历

暴力求解要遍历两次,枚举出所有的组合。能不能只遍历一次

我们想求最大利润,那假设遍历一次数组,每次考虑在第i天卖掉,那以什么价格买入会赚的最多呢?当然是第i天之前,所有的那些天里价格最低的那天买入,利润会更高。所以我们就可以遍历一次数组,每次用minp保存到目前为止的价格最低点,计算当前价格卖掉,之前的minp价格买入的利润,然后保存下最大的利润。

因为每一次遍历i,都会得到i这天卖掉能得到的最大利润(因为买入价格是用之前所有天里的最低点指定的),然后所有这些i的最大利润之间,取一个最大值,就是整体的最大利润。这个所有i的比较,依然可以在遍历的同时比较,把更大的那个值保存下来。

var maxProfit = function(prices) {
    let minp=prices[0],max=0
    for(let i=1;i<prices.length;i++){
        max=Math.max(max,prices[i]-minp)
        minp=Math.min(minp,prices[i])
    }
    return max
};