聊聊买卖股票的最佳时机
前言
大家好,我是大賽哥,好久不見,天天想念!
最近梳理高頻動態規劃問題,股票問題當然是非常經典的動態規劃問題,并且整個系列有好幾道題,這里我整理了6道股票系列的經典問題分享給大家,咱們今天聊聊買賣股票的最佳時機。
想當初頭一次刷股票問題時候,刷了股票問題一二三,但是完全沒用到股票問題的核心思想,當時股票問題一、二不用dp反而也很容易,股票問題三當時自己想到用雙向dp過的,完全沒get股票問題的核心,這次重新梳理,深入get股票問題的核心思想。
股票問題,一定要理解持有和不持有股票兩個相對立狀態以及其變化聯系。這里持有我用hold表示、不持有用dpSell表示(最后結果基本從不持有中獲得),然后有人將這兩個參數整合一個參數數組,[0]表示持有[1]表示不持有,但是個人覺得那樣不太直觀并且效率沒啥區別,所以這里對某些地方不進行優化。
另外dp問題很多時候要設大一位空間、有的從1開始遍歷,很多人會混淆0、第0、第1這些東西,這里我為了減少迷糊0號位置(理論是第一個天)我就給它叫第0天統一減少混淆。
雖然說學會了還是不能學會買賣股票,但是學會了能面對面試官,認真看完你一定會有所收獲!
買賣股票的最好時機(一)
描述:
假設你有一個數組prices,長度為n,其中prices[i]是股票在第i天的價格,請根據這個價格數組,返回買賣股票能獲得的最大收益
1.你可以買入一次股票和賣出一次股票,并非每天都可以買入或賣出一次,總共只能買入和賣出一次,且買入必須在賣出的前面的某一天
2.如果不能獲取到任何利潤,請返回0
3.假設買入賣出均無手續費
分析:
股票問題是非常經典的動態規劃問題,我們分析題目條件可以找到這些重要信息:
總計只能買一次,也總計只能賣一次
買在賣的前面
根據這個信息其實不用動態規劃的思想我們也很容易解決,如果用普通方法也能解決,最笨的方法就是兩層循環,第一層枚舉每個元素第二層枚舉這個元素后面的最大價格的股票,求得最大的股票差即可。
但是那樣肯定是會超時的,優化一下一次枚舉也可以解決這個問題,就是用一個變量min標記順序枚舉出現過的最小值,用一個變量value記錄最大利潤,每次枚舉的數值和出現過的最小min比較是否更新min,作差比較是否更新最大利潤value,最終返回最大利潤即可。
實現的代碼為:
public?int?maxProfit?(int[]?prices)?{//?write?code?hereif(prices.length<2)return??0;int?value=0;//最大利潤int?min=prices[0];//記錄出現的最小股票for(int?i=0;i<prices.length;i++){if(prices[i]<min)//看看是否更新minmin=prices[i];if(prices[i]-min>value)//看看是否更新valuevalue=prices[i]-min;}return??value; }時間復雜度:O(n),空間復雜度:O(1)。
但是這個系列的問題是經典動態規劃的問題,我們重點肯定還是要考慮動態規劃的方法解決,這里有個持有股票和不持有股票的概念,我們用hold[]表示持有股票,dpSell[]表示不持有股票。hold[i]表示到第i天時持有股票時候的最高利潤(這里暫時為負數,因為只能買一次,遇到低的股票值就更新),dpSell[i]表示第i天不持有股票時候的最大利潤(這個利潤要么是繼承前一天的最大利潤,要么是在當天賣了股票獲取的利潤)。
確定dp數組含義:這個問題的環境不難想出dpSell[i]為前i天不持股(已經賣出)買賣股票獲得的最大利潤。
確定遞推式:思考hold[i]和前面數據關系,因為只能買賣一次所以這個持有僅有后面被使用有效,一旦有更低的價格就更新所以hold[i]=max(hold[i-1],-prices[i])。
思考dpSell[i]和前面數據的關系,假設知道前i-1天的所有最大利潤值,那么第i天獲得最大利潤的情況有兩種:
第一種情況是第i天什么也不做,其最大利潤還是前i-1天的利潤(這種 情況一般來說第i天股票數據沒那么亮眼),此時dpSell[i]=dpSell[i-1];第二種情況是第i天剛好賣了股票賺的利潤是前i天獲得的最大利潤,此時需要在前i-1天手頭有一支股票(并且是出現的價格最低的)才行即dpSell[i]=hold[i-1]+prices[i]。
在這個關系中,不持有股票dpSell[]是跟持有股票hold[]有關系,但是hold[]持有股票是相對獨立,我們可以先看持有股票的情況,然后在此基礎上分析不持有股票dpSell[],通過下面案例你可以更好的理解這其中的關系:
初始化dp數組:考慮0號位置、邊緣位置以及特殊情況的一些值。這里根據遞推式和實際知道只需要考慮0號位置的情況,第0天時候如果要持有只能買當天股票那么hold[0]=-prices[0],但是第0天不持有股票最大利潤只能為0(不買)。
那么完整的狀態轉移方程為:
hold[i]=max(hold[i-1],-prices[i])?//i>=1?以前就有最低的??或者以前不持?今天才持最低的 dpSell[i]=max(dpSell[i-1],hold[i-1]+prices[i])//i>=1?今天不賣最高利潤和前面一樣?或者今天賣了才獲得最高利潤 hold[0]=-prices[0] dpSell[0]=0確定遍歷順序:只需要初始0號位置,從1到最后順序進行dp遞推即可。
具體實現的代碼為:
public?int?maxProfit?(int[]?prices)?{//?write?code?hereint?hold[]=new?int[prices.length];//持有int?dpSell[]=new?int[prices.length];//不持有hold[0]=-prices[0];//第0?必須買?這里用負數?后面直接max比較即可dpSell[0]=0;for(int?i=1;i<prices.length;i++){//持有的最大(負數其實是最便宜的)?要么前面的最便宜的?要么今天的hold[i]=Math.max(hold[i-1],-prices[i]);//不持有股票的最大利潤,要么前面利潤就挺大,要么今天股票價格很高和昨天持有差利潤更大dpSell[i]=Math.max(dpSell[i-1],prices[i]+hold[i-1]);}return?dpSell[prices.length-1]; }時間復雜度:O(n),空間復雜度:O(n)。
買賣股票的最好時機(二)
題意
假設你有一個數組prices,長度為n,其中prices[i]是某只股票在第i天的價格,請根據這個價格數組,返回買賣股票能獲得的最大收益
你可以多次買賣該只股票,但是再次購買前必須賣出之前的股票
如果不能獲取收益,請返回0
假設買入賣出均無手續費
分析
這個拓展和前面問題一是有區別的,區別就是可以多次買賣股票(就是這點區別需要我們思考),但是同樣每個時間段手中只能握著一支股票。
如果不用動態規劃的思想,其實每次就比較相鄰的兩個決定是否買賣也能解決這個問題,但這里我們要用動態規劃的思維去解決這個問題,有了上面一題的經驗,相比這題解決起來并不是特別困難,套路也是差不多的。
確定dp數組含義:同上一樣,我們用hold[]表示持有股票,dpSell[]表示不持有股票,hold[i]表示到第i天持有股票的最大利潤,dpSell[i]為到第i天不持股(已經賣出)買賣股票獲得的最大利潤。
確定遞推式:思考hold[i]和前面數據關系,持股的最大利潤要么不變和前i-1天一樣,要么就是第i天持有股票,那么需要拿前i-1天不持有股票的最大利潤加上今天的股票價格,即hold[i]=max(hold[i-1],dpSell[i-1]-prices[i]),這里注意hold[i]不一定是負數,因為有可能前面的已經賺了很多導致hold[]變大。
思考dpSell[i]和前面數據的關系,假設知道前i-1天的所有最大利潤值,那么第i天獲得最大利潤的情況有兩種:
第一種情況是第i天什么也不做,此時dpSell[i]=dpSell[i-1];第二種情況是第i天剛好賣了股票賺的利潤是前i天獲得的最大利潤,此時需要在前i-1天手頭有一支股票(并且是出現的價格最低的)才行即dpSell[i]=hold[i-1]+prices[i]。
初始化dp數組:這里初始化只需要考慮0號位置的持有hold[0]=-prices[0];表示初始狀態需要持有的時候必須購買。
那么完整的狀態轉移方程為:
hold[i]=max(hold[i-1],dpSell[i-1]-prices[i])?//i>=1 dpSell[i]=max(dpSell[i-1],hold[i-1]+prices[i])//?i>=1 hold[0]=-prices[0] dpSell[0]=0確定遍歷順序:從1到最后順序進行dp遞推即可。
具體實現代碼為:
public?int?maxProfit(int[]?prices)?{int?hold[]=new?int[prices.length];//持有int?dpSell[]=new?int[prices.length];//不持有hold[0]=-prices[0];//初始化?持有只能買dpSell[0]=0;for(int?i=1;i<prices.length;i++){//持有最大?要么前一個i-1最大,要么前一個不持股最大買第i個hold[i]=Math.max(hold[i-1],dpSell[i-1]-prices[i]);//不持股最大?要么前一個i-最大,要么前一個i-1持有最大然后第i天賣了dpSell[i]=Math.max(dpSell[i-1],prices[i]+hold[i-1]);}?return?dpSell[prices.length-1]; }時間復雜度:O(n),空間復雜度:O(n)。
買賣股票含冷凍期
描述
給定一個整數數組prices,其中第 prices[i] 表示第 i 天的股票價格 。
設計一個算法計算出最大利潤。在滿足以下約束條件下,你可以盡可能地完成更多的交易(多次買賣一支股票):
賣出股票后,你無法在第二天買入股票 (即冷凍期為 1 天)。
分析
這個問題和前一個問題很相似,就不詳細展開詳細講解,我們考慮一下冷凍期對誰影響了就可以。
遞推分析:我們考慮持有和不持有兩個遞推式有什么變化:
hold[i]第i天持有股票的最大值,第一種可能不做事繼承前一天hold[i-1]是完全有可能的,第二種情況就是我想今天買入,但是賣出的話第二天無法買入有一天冷凍期,所以想今天(第i天)買入只能在第i-2天賣出不持有,然后第i-1天為冷凍期,今天第i天才能買入。
dpSell[i]第i天不持有股票的最大值,第一種可能不做事繼承前一天dpSell[i-1]是完全有可能的,第二種情況就是我想今天賣出,那么前一天買第二天賣是可行的(不受冷凍期影響,冷凍只會凍結賣后的一天不能買),所以第二種可能就是前一天第i-1天持有的最大然后今日賣出加上prices[i]。
那么遞推式:
hold[i]=max(hold[i-1],dpSell[i-2]-prices[i]); dpSell[i]=max(dpSell[i-1],hold[i-1]+prices[i]);初始化考慮:根據遞推式知道買入時候可能和前面兩個數據有關系,所以我們需要初始0、1兩個位置的數據,hold[0]=-prices[0]表示當天持有必買第0天,而hold[1]=max(-prices[0],-prices[1]);則是選擇兩天比較低的股價(因為這時候不會產生賣出的利潤)。dpSell[0]=0表示最大利潤為0,dpSell[1]=max(0,hold[0]+prices[1])表示最大要么是0,要么是昨天買今天賣。
確定遍歷順序:初始0,1號位置數據,從2開始遍歷到最后遞推即可。
具體實現代碼為:
public?int?maxProfit(int[]?prices)?{if(prices.length<=1)return?0;int?hold[]=new?int[prices.length];int?dpSell[]=new?int[prices.length];hold[0]=-prices[0];hold[1]=Math.max(-prices[0],-prices[1]);dpSell[1]=Math.max(dpSell[0],hold[0]+prices[1]);for(int?i=2;i<prices.length;i++){hold[i]=Math.max(hold[i-1],dpSell[i-2]-prices[i]);dpSell[i]=Math.max(dpSell[i-1],hold[i-1]+prices[i]);}return?dpSell[prices.length-1]; }時間復雜度:O(n),空間復雜度:O(n)。
買賣股票的最佳時機含手續費
描述
給定一個整數數組 prices,其中 prices[i]表示第 i 天的股票價格 ;整數 fee 代表了交易股票的手續費用。
你可以無限次地完成交易,但是你每筆交易都需要付手續費。如果你已經購買了一個股票,在賣出它之前你就不能再繼續購買股票了。
返回獲得利潤的最大值。
分析
有了前面解決問題的基礎,這個問題也不難解決了,其實這個問題和無限次購買區別不大,只是每次購買都有手續費。分析一下持有和不持有兩種狀態推導:
hold[i]繼承前一天,或者前一天不持有最大減去今日股價,遞推方式沒變化。
dpSell[i]繼承前一天,或者前一天持有最大加上今日股價,再加上fee的手續費,遞推變化一點點。
遞推式為:
hold[i]=max(hold[i-1],dpSell[i-1]-prices[i]); dpSell[i]=max(dpSell[i-1],hold[i-1]+prices[i]-fee);具體實現代碼為:
public?int?maxProfit(int[]?prices,?int?fee)?{int?hold[]=new?int[prices.length];int?dpSell[]=new?int[prices.length];hold[0]=-prices[0];for(int?i=1;i<prices.length;i++){hold[i]=Math.max(hold[i-1],dpSell[i-1]-prices[i]);dpSell[i]=Math.max(dpSell[i-1],hold[i-1]+prices[i]-fee);}return?dpSell[prices.length-1]; }時間復雜度:O(n),空間復雜度:O(n)。
買賣股票的最好時機(三)
描述
假設你有一個數組prices,長度為n,其中prices[i]是某只股票在第i天的價格,請根據這個價格數組,返回買賣股票能獲得的最大收益
你最多可以對該股票有兩筆交易操作,一筆交易代表著一次買入與一次賣出,但是再次購買前必須賣出之前的股票
如果不能獲取收益,請返回0
假設買入賣出均無手續費
分析
其實這個問題比起上面就難一些,這里面提供兩個思考的角度。
方法一:左右兩個方向dp
前面我們解決過只能買賣一次的動態規劃思路解決這個問題,但是股票買賣獲取利潤的實質是:低買高賣。
一般來說是從左向右進行枚舉,但是想一下從右向左可以不?當然可以啊,從左向右就是記錄一個最低價的股票與枚舉值進行差值計算利潤。而從右向左同樣記錄最大值然后向左枚舉計算差值可以算出從右向左這個區間的最大利潤。
知道從左向右和由右向左兩個方向,有什么作用呢?兩次買賣股票,對應兩個區間一個左側一個右側,那么我們分別計算從左向右的買一次最大利潤和從右向左計算買入一次的最大利潤,然后每個位置dpLeft[i]和dpRight[i]值相加得到一個最大的即可!
public?int?maxProfit(int[]?prices)?{int?dpleft[]=new?int[prices.length];//從左向右的最大利潤int?dpright[]=new?int[prices.length+1];//從右向左的最大利潤if(prices.length<2)return??0;int?value=0;//記錄最大的那個int?low=prices[0];for(int?i=1;i<prices.length;i++){dpleft[i]=dpleft[i-1];//先繼承左側,然后判斷買賣是否能夠獲得更大利潤if(prices[i]<low)?{//看看能否更新買入的最低值low?=?prices[i];continue;}int?num=prices[i]-low;//看看dp值有沒有更新if(num>dpleft[i-1])?{dpleft[i]?=num;}}int?high=prices[prices.length-1];for(int?i=prices.length-2;i>=0;i--){dpright[i]=dpright[i+1];if(prices[i]>high){high=prices[i];continue;}int?num=high-prices[i];//看看dp值有沒有更新if(num>dpright[i+1]){dpright[i]=num;}}for(int?i=1;i<prices.length;i++){int?money=dpleft[i]+dpright[i];if(money>value)value=money;}return??value; }
時間復雜度:O(n),空間復雜度:O(n)。
法二:順序兩次dp
上面方法屬于一個小技巧,但是這個問題如果常規的從左向右正常思維解決該如何處理呢?
確定dp數組含義:我們分析一下這個過程,正常買賣兩次股票有四個步驟同時也對應四個數組:第一次(買入)持有hold1[],第一次(賣出)不持有dpSell1[],第二次(買入)持有hold2[],第二次(賣出)不持有dpSell2[]。
確定遞推式:我們需要分析這些數據有什么關系,我們根據前面的問題很清楚hold1和dpSell1是有關系的,在這里我把他們的關系再給大家梳理一遍:
第一次買入hold1[i]:要么和第i-1天第一次持有的最大利潤相同,要么就是-prices[i]第一次持有最大利潤,即hold1[i]=max(hold[i-1],-prices[i])。
第一次不持有dpSell1[i]:要么和第i-1天第一次不持有dpSell1[i]相同,要么和第i-1天第一次持有利潤加上第i天價格(賣出),即dpSell1[i]=max(dpSell[i-1],hold1[i-1]+price[i])。
第二次持有hold2[i]:要么和i-1天第二次持有的最大利潤相同,要么就是第i-1天第一次不持有的最大利潤減去prices[i],即要么不動跟昨天一樣,要么就是昨天第一次不持有(昨天已經買賣第一次)然后今天再買入時候最大,即hold2[i]=max(hold2[i-1],dpSell1[i-1]-prices[i])。
第二次不持有dpSell2[i]:要么和第i-1天第二次不持有最大利潤相同,要么和第i-1天第二次持有利潤加上第i天價格(賣出),即mdpSell2[i]=ax(dpSell2[i-1],hold2[i-1]+prices[i])。
初始化dp數組:hold1[0]=hold2[0]=-prices[0],即第一次第二次買入時候均購買第0天價格股票。
確定遍歷順序:只需要初始0號位置,從1開始順序枚舉同時進行第一次第二次的動態規劃遞推。
實現的代碼為:
public?int?maxProfit?(int[]?prices)?{//?write?code?hereint?hold1[]=new?int[prices.length];//第一次持有int?dpSell1[]=new?int[prices.length];//第一次不持有int?hold2[]=new?int[prices.length];//第二次持有int?dpSell2[]=new?int[prices.length];//第二次不持有hold1[0]=hold2[0]=-prices[0];for(int?i=1;i<prices.length;i++){hold1[i]=Math.max(hold1[i-1],-prices[i]);dpSell1[i]=Math.max(dpSell1[i-1],prices[i]+hold1[i-1]);hold2[i]=Math.max(hold2[i-1],dpSell1[i-1]-prices[i]);dpSell2[i]=Math.max(dpSell2[i-1],hold2[i-1]+prices[i]);}return?dpSell2[prices.length-1]; }時間復雜度:O(n),空間復雜度:O(n)。
買賣股票的最好時機(四)
描述
1 你最多可以對該股票有k筆交易操作,一筆交易代表著一次買入與一次賣出,但是再次購買前必須賣出之前的股票
2 如果不能獲取收益,請返回0
3 假設買入賣出均無手續費
分析
這個問題和買賣股票的最好時機(三)有些相似,但是是它的變形題。相信到這里,你對持有股票hold、不持有股票dpSell的最大利潤的概念已經理解的很透徹了。咱們前面的問題都是主要在搞明白持有股票hold、不持有股票dpSell最大利潤之間以及天數i的聯系。
我們簡單回顧一下前面的股票問題主要的狀態轉移方程:
股票問題(一):只能購買一次,持有可以繼承前一天或者選今天最低-prices[i](本來是0持有后花錢就變成負的了),不持有可以繼承前一天最低或計算今天出售利潤選擇高的那個。
hold[i]=max(hold[i-1],-prices[i])? dpSell[i]=max(dpSell[i-1],hold[i-1]+prices[i])股票問題(二):可購買股票多次,這時候不持有dpSell[i]和買賣股票(一)其實是沒區別的,要么繼承前一天,要么今日股價加上截止昨日不持有的最大利潤;
但是持有股票hold[i]的最大利潤計算方式有所變化,這里面允許多次交易,那么持有最大的利潤就是前一天不持有的最大利潤dpSell[i-1]加上今天的股價(即今天賣出)或者今天不動繼承昨天的最大利潤。股票(一)受到只能買一次影響所以不能使用前一天不持有d最大利潤來計算。
hold[i]=max(hold[i-1],dpSell[i-1]-prices[i])? dpSell[i]=max(dpSell[i-1],hold[i-1]+prices[i])股票問題(三):可以購買兩次,這個和只能買一次和購買任意次又有所區別,但是前面也分析過購買一次(hold1[i]、dpSell1[i])是和前面股票(一)是一樣處理。
但是購買第二次的問題考慮是在購買第一次的基礎上的。第二次持有hold2[i]要么繼承前一天要么是前一天第一次不持有(dpSell1[i])然后今日購買;第二次不持有dpSell2[i]要么繼承前一天要么是前一天第二次持有最大加上今日股價(今天賣掉)。
hold1[i]=max(hold1[i-1],-prices[i]); dpSell1[i]=max(dpSell1[i-1],hold1[i-1]+prices[i]);hold2[i]=max(hold2[i-1],dpSell1[i-1]-prices[i]); dpSell2[i]=max(dpSell2[i-1],hold2[i-1]+prices[i]);其實這個問題和股票(三)問題很相似,股票一二是弄明白股票利潤與天數的關系,股票三是弄明白兩次買賣股票的關系,而這個問題允許買賣K次股票(同時手中只允許有一支股票),我們來詳細分析一下這個問題:
確定dp數組含義:股票三買賣兩次我們創建了兩對數組,這個k次當然要提高維度來解決,創建hold[prices.length][k+1]、dpSell[prices.length][k+1],其中hold[i][j+1]表示第i天第j次持有股票的最大利潤,dpSell[i][j+1]表示第i天第j次不持有股票的最大利潤,至于為什么設置成k+1后面再說明。
確定遞推式:我們要分析hold[i][j]和dpSell[i][j]和前面數據之間的關系。
hold[i][j]:到第i天第j次持有,它的值可能是前一天(i-1)持有j次最大值hold[i-1][j],另外一個可能情況是前一天(i-1)的第j-1次不持有最大然后買入今日股票(昨天剛賣了,然后今天買入),即dpSell[i-1][j-1]-prices[i]。
dpSell[i][j]:到第i天第j次不持有,它的值可能是前一天(i-1)不持有j次最大值dpSell[i-1][j],還有可能是前一天(i-1)的第j次持有最大然后賣出今日股票(昨天的第j次買入最大,然后今天賣了),即hold[i-1][j]+prices[i]。
這個持有和不持有對應的其實是這么一個二維結構:
總結一下除了繼承前一天的持有或者不持有之外:
hold持有:前一天(i-1)的上次(j-1)不持有減去今日股價。(前一次不持有買賣結束了,再買就是下一次)
dpSell不持有:前一天(i-1)的這次(j)持有加上今日股價。(前一次持有,說明還沒賣出去,那么這一次j還沒結束,自己計算完才算結束)
完整遞推式為:
hold[i][j]=max(hold[i-1][j],dpSell[i-1][j-1]-prices[i]);//前一天同次數?或者前一天不持有上一次的?今天買 dpSell[i][j]=max(dpSell[i-1][j],hold[i-1][j]+prices[i]);//前一天同次數?或者前一天持有的通次?今天賣初始化dp數組:根據前面遞推,和前面初始化,我們知道第0天持有必須購買prices[0]的股票,所以不管第0天的第幾次持有dp[0][j]=0,但是上面根據公式知道第j次可能會用到j-1,這里j是我們新定義的一個含義變量,我們讓它從1開始計數,讓0號位置的數據能夠滿足初始遞推成功進行即可,就不用考慮j初始的特殊情況了,所以前面的k+1是這么來的。
確定遍歷順序:外層i從1開始到prices.length-1枚舉里面處理第i天的持有和不持股票有最大利潤,內層j從1到k表示表示計算這第i天第j次購買的最大利潤(i天數從0開始有效計數,j次數從1開始有效計數)。
具體實現代碼為:
public?int?maxProfit(int?k,?int[]?prices)?{if(prices.length==0)return?0;int?hold[][]=new?int[prices.length][k+1];int?dpSell[][]=new?int[prices.length][k+1];for(int?i=1;i<k+1;i++){hold[0][i]=-prices[0];}hold[0][0]=-prices[0];for(int?i=1;i<prices.length;i++){for(int?j=1;j<k+1;j++){hold[i][j]=Math.max(hold[i-1][j],dpSell[i-1][j-1]-prices[i]);dpSell[i][j]=Math.max(dpSell[i-1][j],hold[i-1][j]+prices[i]);}}//System.out.println(Arrays.deepToString(dpSell));return?dpSell[prices.length-1][k];}結語
到這里,動態規劃系列的股票問題就介紹完畢了,后面還會分享一些其他經典問題。
文中一些內容可能寫的比較粗糙或者有差錯,有細心的大佬發現問題還請指出!會更新到我的倉庫中,大家閱讀原文可以支持一下!
這個忙碌的日子里,大家一起卷起來!
推薦閱讀:
??打家劫舍的智慧!
??備戰藍橋杯 ?這樣準沒錯!
??動態規劃,它來了
? 必須干掉這10道,面試100%遇到!
歡迎關注?「bigsai」,后臺加我拉你進力扣打卡小隊
原創不易,希望路過彥祖仙女點個贊、再看
總結
以上是生活随笔為你收集整理的聊聊买卖股票的最佳时机的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 字节面试必须拿下的十道算法题,你会几道?
- 下一篇: 热乎着,昨晚阿里这题真太绝了