LeetCode121-买卖股票的最佳时机 | 算法练习系列

483 阅读3分钟

这是我参与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循环的暴力解法,它超时了。。。

超时.PNG

  • 这一题的高级解法其实是动态规划,这种方法只进行一次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循环也是能解决的,但动态规划真的会让我们的代码得到极大的提升,但最重要的还是思路(我的思路就不太行,还是要加油啊)