「这是我参与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,有空就会更新,大家多多支持,点个赞👍
如果大家有好的解法,或者发现本文理解不对的地方,欢迎留言评论 😄