题目名称:买卖股票的最佳时机
给定一个数组,它的第 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。
解法
1. 暴力解
- 可以采用暴力解法,从第一天开始买,记录之后所有天卖出的结果中最大值;依次记录第二天,第三天……第n天买到最后一天卖出的最大值
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function (prices) {
if (!prices || !prices.length) return 0
const len = prices.length
let max = 0,
cur = 0,
next = 0
for (let i = 0; i < len; i++) {
cur = prices[i]
for (let j = i + 1; j < len; j++) {
next = prices[j]
if (cur < next) {
max = Math.max(max, next - cur)
}
}
}
return max
}
2. 最低价格递推法
- 由于先买后卖,依次向后推进过程中,只需要跟踪最小值和最大差值即可
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit1 = function (prices) {
if (!prices || !prices.length) return 0
let min = prices[0] // 最小值
let res = 0 // 最大差值
for (let i = 0; i < prices.length; i++) {
min = Math.min(min, prices[i])
res = Math.max(res, prices[i] - min)
}
return res
}
结合代码查看基本原理:
如何能保证这个思考方式有效?
- 极限情况:后面出现了min值更小的情况
根据推算发现,即使后面出现min值更小的情况,仍然能保证第二天买第三天卖获利最高,因为max在单次循环中得到了保留
测试用例
// 测试用例
let test = [7, 1, 5, 3, 6, 4]
let test1 = [7, 6, 4, 3, 1]
console.time("执行用时")
console.log(maxProfit(test))
console.log(maxProfit(test1))
console.log(maxProfit1(test))
console.log(maxProfit1(test1))
console.timeEnd("执行用时")
总结
- 单次循环,跟踪最小值和最大差值即可
说明
- 本题解已同步GitHub地址,可以复制代码进行调试。
- 总结出了一套亲测有效的前端无痛刷题项目,有助于算法小白平稳入门,详见leetcode-js-roadmap,希望对从零开始刷题的前端小伙伴们带来帮助~
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!