<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          ?LeetCode刷題實(shí)戰(zhàn)121:買賣股票的最佳時(shí)機(jī)

          共 1313字,需瀏覽 3分鐘

           ·

          2020-12-16 21:17

          算法的重要性,我就不多說(shuō)了吧,想去大廠,就必須要經(jīng)過(guò)基礎(chǔ)知識(shí)和業(yè)務(wù)邏輯面試+算法面試。所以,為了提高大家的算法能力,這個(gè)公眾號(hào)后續(xù)每天帶大家做一道算法題,題目就從LeetCode上面選 !

          今天和大家聊的問(wèn)題叫做?買賣股票的最佳時(shí)機(jī),我們先來(lái)看題面:
          https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock

          Say you have an array for which the ith element is the price of a given stock on day i.


          If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit.


          Note that you cannot sell a stock before you buy one.


          題意


          給定一個(gè)數(shù)組,它的第 i 個(gè)元素是一支給定股票第 i 天的價(jià)格。
          如果你最多只允許完成一筆交易(即買入和賣出一支股票一次),設(shè)計(jì)一個(gè)算法來(lái)計(jì)算你所能獲取的最大利潤(rùn)。
          注意:你不能在買入股票前賣出股票。

          樣例


          示例 1:

          輸入: [7,1,5,3,6,4]
          輸出: 5
          解釋: 在第 2 天(股票價(jià)格 = 1)的時(shí)候買入,在第 5 天(股票價(jià)格 = 6)的時(shí)候賣出,最大利潤(rùn) = 6-1 = 5 。
          ?????注意利潤(rùn)不能是 7-1 = 6, 因?yàn)橘u出價(jià)格需要大于買入價(jià)格;同時(shí),你不能在買入前賣出股票。

          示例 2:

          輸入: [7,6,4,3,1]
          輸出: 0
          解釋: 在這種情況下, 沒(méi)有交易完成, 所以最大利潤(rùn)為 0。



          解題

          https://www.cnblogs.com/gzshan/p/11114066.html

          解法一:Brute Force暴力解法
          由于限制只允許一次交易,那么一個(gè)最直觀的解法就是對(duì)每一天,都依次遍歷它之后的所有可能賣出的情況,記錄最大值,最后進(jìn)行比較得出最終結(jié)果。很顯然這是一個(gè)二重循環(huán),時(shí)間復(fù)雜度為O(n^2),空間復(fù)雜度:O(1)。
          換句話說(shuō),這也就是將所有可能的買賣情況都窮舉出來(lái),然后找最大值。


          public?int?maxProfit(int[] prices) {
          ????????//解法一:蠻力法,找到每一天后續(xù)的最大值,比較確定最大利潤(rùn)
          ????????//時(shí)間復(fù)雜度:O(n^2),空間復(fù)雜度:O(1)
          ????????if(prices==null?|| prices.length==0)
          ????????????return?0;
          ????????int?maxprofit=0;
          ????????for(int?i=0;i????????????for(int?j=i+1;j//如果第i天買入,依次判斷它之后的每一天賣出的情況
          ????????????????if(prices[j]-prices[i]>maxprofit)
          ????????????????????maxprofit=prices[j]-prices[i];
          ????????????}
          ????????}
          ????????return?maxprofit;
          ????}



          解法二:動(dòng)態(tài)規(guī)劃法

          暴力法需要二重循環(huán),解法二通過(guò)動(dòng)態(tài)規(guī)劃使得只需要一次遍歷即可找到最大值,動(dòng)態(tài)規(guī)劃適用于多階段決策過(guò)程的最優(yōu)化問(wèn)題,明顯這里就是一個(gè)決定什么時(shí)候買和賣出的階段決策問(wèn)題。

          如果我們用dp[i]表示從第1天到第i天進(jìn)行一筆交易能獲得的最大收益,用min表示買入時(shí)的價(jià)格(最低的時(shí)候),則dp[i]=max(price[i]-min,dp[i-1]),其中maxProfit是指已經(jīng)找到的最大收益。

          在求出所有的dp[i]以后我們?cè)僬业狡渲械淖畲笾担礊樗笾担捎谥恍枰业阶畲笾担虼丝梢院隙橐唬闅v的過(guò)程中順便求最大值,因此遞推公式變?yōu)椋?/span>
          dp[i]=max(price[i]-min,maxProfit)

          由于只允許一次交易,所以要想獲得最大收益,必須在價(jià)格最低的時(shí)候買入,最高的時(shí)候賣出,但是由于必須先買后賣,所以如果用波形來(lái)說(shuō),就是要找到一個(gè)波峰和波谷,波谷在波峰之前。


          ? 在這里,我們只需要維護(hù)一個(gè)min變量,就可以省去一層循環(huán),代碼如下:


          public?int?maxProfit(int[] prices) {
          ????????//解法二:動(dòng)態(tài)規(guī)劃法:用dp[i]表示第i天賣出的收益,則dp[i]=max(price[i]-min,maxProfit)
          ????????//時(shí)間復(fù)雜度:O(n),空間復(fù)雜度:O(1)
          ????????if(prices==null?|| prices.length==0)
          ????????????return?0;
          ????????int?len=prices.length;
          ????????int?maxprofit=0,min=Integer.MAX_VALUE;
          ????????for(int?i=0;i????????????if(prices[i]//維護(hù)一個(gè)最小值
          ????????????????min=prices[i];
          ????????????else?if(prices[i]-min>maxprofit)
          ????????????????maxprofit=prices[i]-min;
          ????????}
          ????????return?maxprofit;
          ????}


          總結(jié):以上兩種解法實(shí)際上都比較好理解,實(shí)際上,暴力法就是我們先確定哪一天買,這樣賣出的選擇就需要遍歷,而動(dòng)態(tài)規(guī)劃法,我們是先確定哪一天賣,由于題目的特點(diǎn),那么買的時(shí)間就是賣之前的最小值,正好在這個(gè)遍歷的過(guò)程中我們就能把這個(gè)最小值記錄下來(lái),因此得到了性能的提升。


          好了,今天的文章就到這里,如果覺(jué)得有所收獲,請(qǐng)順手點(diǎn)個(gè)在看或者轉(zhuǎn)發(fā)吧,你們的支持是我最大的動(dòng)力。


          上期推文:

          LeetCode1-120題匯總,希望對(duì)你有點(diǎn)幫助!


          瀏覽 29
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  看日本黄色片 | 免费av国产 | 天天橾| 四虎影院无码 | 欧美成人乱轮 |