给定一个数组,它的第 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
};