题目:买卖股票的最佳时机
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润。
注意:你不能在买入股票前卖出股票。
示例:
输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票
输入: [7,6,4,3,1] 输出: 0 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
题解:
方法1:暴力解法
step1:如果当前数组为空,直接返回0
step2:如果不为空,用一个变量max来记录当前最大值,进行外层遍历
step3:进程内层遍历,遍历时,需要计算差值,max取当前max与差值的最大值
step4:返回max即为所求
时间负杂度:O(n*n)
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function(prices) {
//暴力解法
if(!prices) return 0
let max = 0,cur = 0
let len = prices.length
for(let i=0;i<len;i++){
let diff
//因为需要先买后卖,所以j=i+1
for(j = i+1;j<len;j++){
//只有卖出大于买入才获益,所以,可以先进行判断
if(prices[j] > prices[i]){
diff = prices[j] - prices[i]
//最大值,为已经记录最大值,与当前卖出获益中取最大值
max = diff>max?diff:max
}
}
}
return max
};
方法2:滑动窗口
step1:定义一个数组,用来存储前i天卖出的最大获益
step2:定义一个变量min,用来记录当前的最小值,假设是最加买入点
step3:遍历数组,更新最小值,然后比较当前值卖出与前i-1天卖出的收益
step4:直接返回数组的最后一项
时间复杂度O(n),空间复杂度O(n)
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function(prices) {
//采用一个数组记录
if(!prices ||!prices.length) return 0
//定一个数组,来存储,前i天卖出第最大收益
let len = prices.length,dp = new Array(len).fill(0)
let min = prices[0]
for(let i=1,price;i<len;i++){
price = prices[i]
min = min<price?min:price
//第i次的最大,只需要比较i-1和当前减去最小值,取最大即可
dp[i] = Math.max(dp[i-1],price-min)
}
return dp[len-1]
};