这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战
前言
每日一道js算法题,今天来一道数组相关的算法题,它的名字叫买卖股票的的最佳时机,当我看到这个题目的时候我竟然有那么一瞬间以为是真的股票。。。下面来看看这道题到底在干嘛吧
题目描述
给定一个数组 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。
解题思路
- 看到这道题目的第一思路就是排序,但认真看了题目的要求后发现不可以,因为要保证卖出一定要在买入前
- 那就用双重for循环,假设每一天都买了股票,然后再在第二次for循环中找到最大值即可,下面上代码
var maxProfit = function (prices) {
let maxValue = 0
let curr = prices[0]
let median = 0
for (let i = 0; i < prices.length - 1; i++) {
curr = prices[i]
for (let j = i + 1; j < prices.length; j++) {
if (prices[j] > curr && (prices[j] - curr > maxValue)) {
maxValue = prices[j] - curr
}
}
}
if (maxValue > 0) {
return maxValue
} else {
return 0
}
};
- 如上代碼,进行两次for循环,得到每天买入股票再之后的某天卖出的最大值,再在所以最大值中找到最大值就得到了可以获得的最大利润,但是由于使用for循环的暴力解法,它超时了。。。
- 这一题的高级解法其实是动态规划,这种方法只进行一次for循环就行了,我们首先声明两个变量,maxProfit和minPrice,在for循环中拿每一项和minPrice进行对比,如果小于minPrice那么就更新minPrice,如果大于minPrice并且这项和minPrice的差值大于maxProfit,那么就更新maxProfit
- 这里需要注意的一点是最大利润为0的情况,还有一个就是minPrice的初始值,这里我用的是数组中数据的最大值,这样做的目的是为了可以遍历所有的数据,当然你把minPrice设置为一个非常大的值也是可以的,反正最小要设置为数组中数据的最大值,下面上代码
var maxProfit = function(prices) {
let maxProfit = 0
let minPrice = Math.max.apply(null,prices)
for(let i=0;i<=prices.length-1;i++){
if(prices[i]<minPrice){
minPrice=prices[i]
}else if(prices[i]-minPrice>maxProfit){
maxProfit = prices[i]-minPrice
}
}
if(maxProfit>0){
return maxProfit
}else{
return 0
}
};
总结
本题分享到此结束,这题其实不算难,就算我们想不到动态规划,使用for循环也是能解决的,但动态规划真的会让我们的代码得到极大的提升,但最重要的还是思路(我的思路就不太行,还是要加油啊)