LeetCode121、 买卖股票的最佳时机

64 阅读2分钟

LeetCode 系列记录我学习算法的过程。

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第19天,点击查看活动详情

题目

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0

示例:

输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,
最大利润 = 6-1 = 5 。注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;
同时,你不能在买入前卖出股票。


输入: prices = [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0

提示:

  • 1 <= prices.length <= 105
  • 0 <= prices[i] <= 104

思路

这个题目的第一眼思路就是使用嵌套循环来遍历所有情况,然后将其中的最大值返回

但是实际操作了后发现超出时间限制了,那没办法,只能想其他方法来解决了

我想到了之前的双指针的方法,发现刚好可以用在这个题目上,而且只需要一次循环即可:

  • 首先我们定义三个变量分别存储最大值、数组长度、最小项指针
  • 从第二项开始遍历数组
  • 如果遍历项小于最小项指针指向的值,那么移动最小项指针到当前项
  • 反之则求出两指针指向的值的差,与记录的最大值进行比较
  • 遍历结束返回记录的最大值即可

代码实现

/**
 * @param {number[]} prices
 * @return {number}
 */
var maxProfit = function(prices) {
    let max = 0, // 记录的最大值
        len = prices.length, // 数组长度
        x = 0 // 指向遍历项前面最小值的指针
     // 遍历数组
    for(let i = 1; i < len; i++) {
        // 如果遍历项的值小于指向的最小项的值
        if(prices[i] < prices[x]) {
            // 那么移动指针
            x = i
        } else {
            // 反之求出两指针指向的值之差,与记录的最大值对比
            max = Math.max(max, prices[i] - prices[x])
        }
    } 
    // 最后返回记录的最大值
    return max
};

image.png