小白刷LeetCode拒绝暴力解法Day1

浅聊一下

作为一名小白,在leetCode刷题数已经达到了三位数,但是在我刷过的大部分题目中,都是使用的暴力解法,多层循环遍历等等...真的是有受够了自己


今天开始,我决定远离暴力解法,学习一下高端烧脑并且优雅的解法( ఠൠఠ )ノ

LeetCode:买卖股票的最佳时机

我们先来看题目:

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

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

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

换做昨天的我估计在想,这这这,简单的不能再简单了,直接双层循环我就给他解决了...

但是今天,我选择用动态规划和贪心来完成这道题

动态规划

我们来看题目最后想要的结果是什么

=>返回你可以从这笔交易中获取的最大利润

注意 最大 这两个字,一般提到最大,我们就要想到动态规划,我们得用动态规划把这题干掉

那动态规划是怎么思考的呢?

  • 自顶而下

    我们要让最后的结果为最优解,自然要让前面的每一步都是最优解,带入题目

    我可以选择今天卖股票,也可以选择昨天卖股票,在今天以前,我们昨天卖掉股票所得的利润是最大的,于是我该和今天比较,如果今天卖的比昨天更多,那么我就今天把股票卖了...

  • 状态转移方程

    根据我们自顶向下的思想,我们可以列出状态转移方程

dp[i] = Math.max(dp[i-1],prices[i]-min)

dp[i]代表第i天卖出股票获利的最大值,如果第i天卖出的利润比dp[i-1]大,那么我们获得的最大利润就为dp[i],并且我们知道,在第一天买入股票之后当天是不能卖出股票的,所以

dp[0] = 0

js 复制代码
var maxProfit = function(prices) {
    const dp = new Array(prices.length).fill(0)
    let min = prices[0]
    for(let i = 1;i<prices.length;i++){
        min = Math.min(prices[i],min)
        dp[i] = Math.max(dp[i-1],prices[i]-min)
    }
    return dp[prices.length-1]
};

我们使用一个数组 dp 来保存每天卖出股票能够获得的最大利润。数组 dp 的长度与股票价格数组 prices 的长度相同。数组 dp 中的每个元素 dp[i] 表示在第 i 天卖出股票能够获得的最大利润。初始值都为0。

然后,我们从数组的第二个元素开始遍历(i = 1),对于每个元素 prices[i],我们进行以下操作:

  1. 计算在前 i-1 天中能够获得的最小买入价格 min。我们使用 Math.min(prices[i],min) 来更新最小买入价格 minprices[i] 表示当前的股票价格,如果这个价格比当前的最小买入价格 min 小,就更新最小买入价格为这个值。
  2. 计算在第 i 天卖出股票能够获得的最大利润。我们使用 Math.max(dp[i-1], prices[i]-min) 来更新数组 dp 中的元素。dp[i-1] 表示在前 i-1 天中获得的最大利润,因为我们不能在同一天既买入又卖出股票。所以,在第 i 天卖出股票的最大利润为 prices[i]-min,即当前股票价格减去前 i-1 天中的最小买入价格。然后,我们使用 Math.max 函数来比较 dp[i-1]prices[i]-min,取其中的较大值作为 dp[i] 的值。

通过遍历完整个数组,我们得到了最大利润。最后,我们返回 dp[prices.length-1] 作为函数的结果。

贪心

我们再来用贪心解决这道题

什么是贪心?就是我很贪心,总是想得到最多的东西...总是做出在当前看来是最好的选择 不从整体最优上加以考虑 算法得到的是局部最优解。

  • 在每一个价格上升的时刻,我们选择将股票卖出以获取最大利润;而在价格下降或持平的时候,我们选择保持最低买入价格。通过这样的策略,我们能够在一次遍历中找到最大利润,而不需要进行多次交易。
js 复制代码
var maxProfit = function(prices) {
   let min = prices[0]
   let profit = 0
   for(let i = 1;i<prices.length;i++){
    if(prices[i] > prices[i-1]){
        profit = Math.max(prices[i]-min,profit)
    }else{
        min = Math.min(prices[i],min)
    }    
   } 
   return profit
};

首先,我们初始化两个变量 minprofitmin 用于记录当前遍历到的最低买入价格,profit 用于记录当前的最大利润,初始值都为0。

然后,我们从数组的第二个元素开始遍历(i = 1),对于每个元素 prices[i],我们进行以下操作:

  1. 如果当前价格 prices[i] 大于前一个价格 prices[i-1],说明股票价格上升了。此时我们可以考虑将其卖出,并计算当前的利润。我们使用 Math.max(prices[i]-min, profit) 来更新当前的最大利润。prices[i]-min 表示将当前股票卖出后的利润,如果这个利润比当前的最大利润 profit 大,就更新最大利润为这个值。
  2. 如果当前价格 prices[i] 小于等于前一个价格 prices[i-1],说明股票价格下降了或者持平了。此时我们需要考虑是否要更新最低买入价格 min。我们使用 Math.min(prices[i], min) 来更新最低买入价格。prices[i] 表示当前的股票价格,如果这个价格比当前的最低买入价格 min 小,就更新最低买入价格为这个值。

通过遍历完整个数组,我们得到了最大利润。最后,我们返回最大利润作为函数的结果。

下班

想当聪明人的第一天完美结束...今天就写到这里吧!对了,最近掘金大大在搞年度优秀创作者投票活动,要是掘友们觉得小弟的文章让您有所收获,就给我投上一票吧!!!

相关推荐
前端大卫几秒前
【Chrome 官方示例】🔥手把手教你解锁 Performace 选项卡
前端·javascript·性能优化
苏州第一深情3 分钟前
SpeechSynthesisUtterance文字语音播报, 循环播报, 方法封装多组件使用, 自定义播报音色音量音调
前端·javascript·vue.js
JiangJiang6 分钟前
Vue3源码:5个问题带你读懂watch
javascript·vue.js·面试
如此风景11 分钟前
TypeScript中的Record
javascript
王小菲14 分钟前
深入解析 JavaScript 闭包机制:从作用域到高阶应用
前端·javascript·面试
bug_kada1 小时前
ES6 字符串新增方法你了解多少?
前端·javascript
梭七y1 小时前
leetcode日记(106)买卖股票的最佳时机Ⅲ
算法·leetcode·职场和发展
宁静_致远2 小时前
React + TypeScript 开发中的黄金法则
javascript
独立开阀者_FwtCoder2 小时前
掌握这个API,让你的网页展示效果提升10倍
前端·vue.js·面试
职豚求职小程序2 小时前
移动笔试丨中国移动笔试2025届笔试考什么?运营商春招攻略、考点技巧|附真题秘籍、题型介绍、面试攻略、求职建议
面试·职场和发展