日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

小白学算法:买卖股票的最佳时机!

發布時間:2025/3/11 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 小白学算法:买卖股票的最佳时机! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者 | 王磊

來源 | Java中文社群(ID:javacn666)

轉載請聯系授權(微信ID:GG_Stone)

本文已收錄至 Github《小白學算法》系列:https://github.com/vipstone/algorith

今天螞蟻集團(支付寶)正式上市了,毫無疑問這一舉措又造就了一大批富豪,然而作為局外人的我們,也只有羨慕的份了。明明可以靠運氣吃飯,咱非得靠實力,你說虧不虧啊?

但話又說回來,能進螞蟻的人也都是牛人,那咱也趕緊提升一下技能吧,好為下一個“螞蟻”做足準備。

今天的這道題比較有意思,是關于「買賣股票」的,題目如下。

題目描述

給定一個數組,它的第 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。

來源:LeetCode

劍指 offer 64:https://leetcode-cn.com/problems/gu-piao-de-zui-da-li-run-lcof/submissions/難度:中

leetcode 121:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/難度:簡單

解題思路

根據題目的意思我們知道,我們只有一次交易的機會,也就是買一次再賣一次,但同時要保證收益最大化。那我們本能的直覺是在最低的價格買入,再在最高的價格賣出就好了,如下圖所示:


但這有一個問題,就是我們要保證最高價格要在最低的價格之后,因為我們必須在購買了股票之后才能賣出,而不是相反的順序,這就讓問題變的復雜了。

但此刻我們想到了一個最直接也是最笨的一個方法,那就是用暴力窮舉法,我們使用兩層循環,依次在每個節點買入,然后再在之后的所有節點賣出,這樣來計算節點間的差值(收益),如果此差值大于當前最高收益,就將此值設置為當前最高收益,這樣循環完,我們就能獲得最大收益了。如下圖所示:


方法一:暴力法

有了上面的思路,接下來我們用代碼實現一下:

class?Solution?{public?int?maxProfit(int[]?prices)?{int?mp?=?0;?//?最高收益for?(int?i?=?0;?i?<?prices.length;?i++)?{for?(int?j?=?i?+?1;?j?<?prices.length;?j++)?{int?item?=?prices[j]?-?prices[i];if?(item?>?mp)?mp?=?item;}}return?mp;} }

可以看出代碼還是很簡單的,但別高興得太早,我們來看它在 leetcode 上的表現:

復雜度分析

  • 時間復雜度:O(n^2),循環運行 n(n-1)/2 次。

  • 空間復雜度:O(1),只使用了常數位的變量。

真是一頓操作猛如虎,最終擊敗百分之五!如果用這種代碼去面試的話,估計只能回去等通知了。那有沒有更好的方法呢?答案是肯定的,繼續往下看。

方法二:遍歷一次

對于這道題我們其實可以使用一次循環來實現,先來看下面的這張折線圖:


從上面的圖片我們可以看出,我們在每個節點其實只會做兩件事(第一個節點除外,只能買入不能賣出),這兩件事分別是:買入或賣出。那么我們其實可以用一個循環來計算出最大的利潤,我們只需要依次對于每個節點做以下兩個判斷:

  • 判斷當前節點是不是相對最低價,如果是,則將它設置為最低價(也就是買入);

  • 如果當前節點不是最低價,那我們就將它賣出,然后計算賣出的收益(當前節點減去相對最低價),如果賣出的收益大于目前的最高收益,則將此值設置為最高收益。

這樣循環完成之后最高收益就出來了,實現代碼如下:

class?Solution?{public?int?maxProfit(int?prices[])?{if?(prices?==?null?||?prices.length?==?0)?return?0;int?mp?=?0;?//?最高收益int?min?=?prices[0];?//?最低價for?(int?i?=?1;?i?<?prices.length;?i++)?{if?(prices[i]?<?min)?{//?設定相對最低價min?=?prices[i];}?else?if?(mp?<?(prices[i]?-?min))?{//?設定最高盈利mp?=?prices[i]?-?min;}}return?mp;} }

以上代碼在 leetcode 中的結果如下圖所示:

復雜度分析

  • 時間復雜度:O(n),只需要遍歷一次。

  • 空間復雜度:O(1),只使用了常數個變量。

從以上的執行的結果可以看出,這段代碼還算是比較理想的,這樣面試官也會對你豎起大拇指了。

總結

本文我們計算了單次(一次買入和賣出)股票的最高收益,剛開始我們使用的是最簡單粗暴的暴力枚舉法,使用兩層循環依次相減來求出最高收益值,但這種方法的執行效率太低。

然后我們經過觀察折線圖發現,只需要一次循環也能找出最高的收益值。我們只需要在每個節點做兩個判斷,第一:判斷此節點是否為相對最小值,如果是,則記錄下來;如果不是,則計算此值和相對最小值是否為當前最高收益,如果是,則記錄下來。那么循環一圈之后,我們就能得出最高的收益了,并且執行的效率也很高。

你學會了嗎?有不懂的地方或者更好的方法,歡迎評論區留言~

往期推薦

算法圖解:如何用兩個棧實現一個隊列?

2020-10-26

Java中的5大隊列,你知道幾個?

2020-10-24

一文詳解「隊列」,手擼隊列的3種方法!

2020-10-21

關注我,每天陪你進步一點點!

總結

以上是生活随笔為你收集整理的小白学算法:买卖股票的最佳时机!的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。