Leetcode經典題6--買賣股票的最佳時機

買賣股票的最佳時機

題目描述:

給定一個數組?prices?,它的第?i?個元素?prices[i]?表示一支給定股票第?i?天的價格。

你只能選擇?某一天?買入這只股票,并選擇在?未來的某一個不同的日子?賣出該股票。設計一個算法來計算你所能獲取的最大利潤。

返回你可以從這筆交易中獲取的最大利潤。如果你不能獲取任何利潤,返回?0?。

輸入輸出示例:

輸入:[7,1,5,3,6,4]

輸出:5

解釋:在第 2 天(股票價格 = 1)的時候買入,在第 5 天(股票價格 = 6)的時候賣出,最大利潤 = 6-1 = 5 。 注意利潤不能是 7-1 = 6, 因為賣出價格需要大于買入價格;同時,你不能在買入前賣出股票。

解題方案:

方式一:暴力求解(不推薦)

算法思路:最低買入,最高賣出 我們需要找出給定數組中兩個數字之間的最大差值(即,最大利潤)。此外,第二個數字(賣出價格)必須大于第一個數字(買入價格)。

形式上,對于每組 i 和 j(其中 j>i)我們需要找出 max(prices[j]?prices[i])。

實現代碼

public class Solution {public int maxProfit(int[] prices) {int maxprofit = 0;//i指向買入時的價格for (int i = 0; i < prices.length - 1; i++) {//j指向賣出時的價格for (int j = i + 1; j < prices.length; j++) {//求出利潤int profit = prices[j] - prices[i];if (profit > maxprofit) {maxprofit = profit;}}}return maxprofit;}
}

復雜度分析

時間復雜度:O(n2)。二重循環,循環運行?2n(n?1)??次。

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

方法二:一次遍歷

算法思想:假設給定的數組為:[7, 1, 5, 3, 6, 4]

如果我們在圖表上繪制給定數組中的數字,我們將會得到:

如果自己購買股票,每天肯定會想:如果股票在歷史最低點賣出就好了

因此,用變量記錄歷史最低點,同時計算自己的股票在第i天賣出能夠獲得的利潤,每天都不斷地更新這兩個變量,從而可以在遍歷一次數組的情況下,就可以獲得最大利潤

class Solution {public int maxProfit(int[] prices) {//初始化變量,最大利潤ans為0,默認第一天prices[0]為股票最低價格買入int ans=0,minPrice=prices[0];//遍歷傳入的數組prices中的每個元素,并把當前元素賦值給變量pfor(int p:prices){//更新最大利潤;計算當前賣出去價格p減去之前的最低買入價格minPrice的利潤;與之前獲取的利潤ans比較,獲取最大利潤ans=Math.max(ans,p-minPrice);//更新最低買入價格,采用當前價格p和之前的最低價minPrice中較小的一個minPrice=Math.min(minPrice,p);}return ans;//返回最大利潤
}
}

買賣股票的最佳時機 進階版

題目描述

給你一個整數數組?prices?,其中?prices[i]?表示某支股票第?i?天的價格。

在每一天,你可以決定是否購買和/或出售股票。你在任何時候?最多?只能持有?一股?股票。你也可以先購買,然后在?同一天?出售。可以在一段時間內買賣多張股票

返回?你能獲得的?最大利潤?。

輸入輸出示例

輸入:prices = [7,1,5,3,6,4]

輸出:7

解釋:在第 2 天(股票價格 = 1)的時候買入,在第 3 天(股票價格 = 5)的時候賣出, 這筆交易所能獲得利潤 = 5 - 1 = 4。隨后,在第 4 天(股票價格 = 3)的時候買入,在第 5 天(股票價格 = 6)的時候賣出, 這筆交易所能獲得利潤 = 6 - 3 = 3。最大總利潤為 4 + 3 = 7 。

解題方案

方式一:動態規劃

算法思想:

定義狀態

dp[i][0] 表示第 i 天交易完后手里沒有股票的最大利潤,

dp[i][1] 表示第 i 天交易完后手里持有一支股票的最大利潤(i 從 0 開始)。

如果這一天交易完后手里沒有股票,考慮 dp[i][0] 的值會有兩種情況:

  • 前一天已經沒有股票,即 dp[i?1][0],
  • 前一天結束的時候手里持有一支股票,即 dp[i?1][1],這時候我們要將其賣出,并獲得 prices[i] 的收益。

如果這一天交易完后手里有股票,考慮 dp[i][1] 的值會有兩種情況:

  • 前一天已經持有一支股票,即 dp[i?1][1]
  • 前一天結束時還沒有股票,即 dp[i?1][0],這時候我們要將其買入,并減少 prices[i] 的收益。

初始條件可以由計算得到 dp[0][0]=0,dp[0][1]=?prices[0]。

由于全部交易結束后,持有股票的收益一定低于不持有股票的收益,因此這時候 dp[n?1][0] 的收益必然是大于 dp[n?1][1] 的,最后的答案即為 dp[n?1][0]。

每一天的狀態只與前一天的狀態有關,而與更早的狀態都無關,因此我們不必存儲這些無關的狀態,只需要將 dp[i?1][0] 和 dp[i?1][1] 存放在兩個變量中,通過它們計算出 dp[i][0] 和 dp[i][1] 并存回對應的變量,以便于第 i+1 天的狀態轉移即可。

實現代碼

class Solution {public int maxProfit(int[] prices) {int n = prices.length;//初始化int dp0 = 0, dp1 = -prices[0];for (int i = 1; i < n; ++i) {//對于每一天,都計算出持有股票的收益和未持有股票的收益,不斷地進行迭代int newDp0 = Math.max(dp0, dp1 + prices[i]);int newDp1 = Math.max(dp1, dp0 - prices[i]);dp0 = newDp0;dp1 = newDp1;}return dp0;}
}
方法二:貪心

算法思想:由于股票的購買沒有限制,因此整個問題等價于尋找?x?個不相交的區間?(li,ri?]?使得如下的等式最大化

其中?li??表示在第?li??天買入,ri??表示在第?ri??天賣出。

?

如圖所示,如果第i天的價格高于第i-1天的價格,則將利潤加入到總利潤當中

需要說明的是,貪心算法只能用于計算最大利潤,計算的過程并不是實際的交易過程

實現代碼:

class Solution {public int maxProfit(int[] prices) {int ans = 0;int n = prices.length;for (int i = 1; i < n; ++i) {ans += Math.max(0, prices[i] - prices[i - 1]);}return ans;}
}

復雜度分析

時間復雜度:O(n),其中?n?為數組的長度。我們只需要遍歷一次數組即可。

空間復雜度:O(1)。只需要常數空間存放若干變量。

歡迎大家點贊,評論加收藏

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/62224.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/62224.shtml
英文地址,請注明出處:http://en.pswp.cn/web/62224.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MCPTT 與BTC

MCPTT&#xff08;Mission Critical Push-to-Talk&#xff09;和B-TrunC&#xff08;寬帶集群&#xff09;是兩種關鍵通信標準&#xff0c;它們分別由不同的組織制定和推廣。 MCPTT&#xff08;Mission Critical Push-to-Talk&#xff09;標準由3GPP&#xff08;第三代合作伙伴…

去除賬號密碼自動賦值時的輸入框背景色

問題描述&#xff1a; 前端使用賬號密碼登錄&#xff0c;若在網頁保存過當前頁面的密碼和賬號&#xff0c;那么當再次進入該頁面&#xff0c;網頁會自動的把賬號和密碼賦到輸入框中&#xff0c;而此時輸入框是帶有背景色的&#xff0c;與周邊的白色背景顯得很不協調&#xff1…

【Pytorch】torch.reshape與torch.Tensor.reshape區別

問題引入&#xff1a; 在Pytorch文檔中&#xff0c;有torch.reshape與torch.Tensor.reshape兩個reshape操作&#xff0c;他們的區別是什么呢&#xff1f; 我們先來看一下官方文檔的定義&#xff1a; torch.reshape&#xff1a; torch.Tensor.reshape: 解釋&#xff1a; 在p…

掃碼與短信驗證碼登錄JS逆向分析與Python純算法還原

文章目錄 1. 寫在前面2. 掃碼接口分析2. 短信接口分析3. 加密算法還原【??作者主頁】:吳秋霖 【??作者介紹】:擅長爬蟲與JS加密逆向分析!Python領域優質創作者、CSDN博客專家、阿里云博客專家、華為云享專家。一路走來長期堅守并致力于Python與爬蟲領域研究與開發工作!…

spring6:3容器:IoC

spring6&#xff1a;3容器&#xff1a;IoC 目錄 spring6&#xff1a;3容器&#xff1a;IoC3、容器&#xff1a;IoC3.1、IoC容器3.1.1、控制反轉&#xff08;IoC&#xff09;3.1.2、依賴注入3.1.3、IoC容器在Spring的實現 3.2、基于XML管理Bean3.2.1、搭建子模塊spring6-ioc-xml…

【認證法規】安全隔離變壓器

文章目錄 定義反激電源變壓器 定義 安全隔離變壓器&#xff08;safety isolating transformer&#xff09;&#xff0c;通過至少相當于雙重絕緣或加強絕緣的絕緣使輸入繞組與輸出繞組在電氣上分開的變壓器。這種變壓器是為以安全特低電壓向配電電路、電器或其它設備供電而設計…

車機端同步outlook日歷

最近在開發一個車機上的日歷助手&#xff0c;其中一個需求就是要實現手機端日歷和車機端日歷數據的同步。然而這種需求似乎沒辦法實現&#xff0c;畢竟手機日歷是手機廠商自己帶的系統應用&#xff0c;根本不能和車機端實現數據同步的。 那么只能去其他公共的平臺尋求一些機會&…

OpenCV-圖像閾值

簡單閾值法 此方法是直截了當的。如果像素值大于閾值&#xff0c;則會被賦為一個值&#xff08;可能為白色&#xff09;&#xff0c;否則會賦為另一個值&#xff08;可能為黑色&#xff09;。使用的函數是 cv.threshold。第一個參數是源圖像&#xff0c;它應該是灰度圖像。第二…

力扣300.最長遞增子序列

題目描述 題目鏈接300. 最長遞增子序列 給你一個整數數組 nums &#xff0c;找到其中最長嚴格遞增子序列的長度。 子序列 是由數組派生而來的序列&#xff0c;刪除&#xff08;或不刪除&#xff09;數組中的元素而不改變其余元素的順序。例如&#xff0c;[3,6,2,7] 是數組 […

Vue CLI的作用

Vue CLI&#xff08;Command Line Interface&#xff09;是一個基于Vue.js的官方腳手架工具&#xff0c;其主要作用是幫助開發者快速搭建Vue項目的基礎結構和開發環境。以下是Vue CLI的具體作用&#xff1a; 1、項目模板與快速生成 Vue CLI提供了一系列預設的項目模板&#x…

【藍橋杯每日一題】掃雷

掃雷 知識點 2024-12-3 藍橋杯每日一題 掃雷 dfs &#xff08;bfs也是可行的&#xff09; 題目大意 在一個二維平面上放置這N個炸雷&#xff0c;每個炸雷的信息有$(x_i,y_i,r_i) $&#xff0c;前兩個是坐標信息&#xff0c;第三個是爆炸半徑。然后會輸入M個排雷火箭&#xff0…

【大數據學習 | 面經】Spark 3.x 中的AQE(自適應查詢執行)

Spark 3.x 中的自適應查詢執行&#xff08;Adaptive Query Execution&#xff0c;簡稱 AQE&#xff09;通過多種方式提升性能&#xff0c;主要包括以下幾個方面&#xff1a; 動態合并 Shuffle 分區&#xff08;Coalescing Post Shuffle Partitions&#xff09;&#xff1a; 當 …

城電科技 | 光伏景觀長廊 打造美麗鄉村綠色低碳示范區 光伏景觀設計方案

光伏景觀長廊是一種結合了光伏發電技術和零碳景觀設計的新型公共公共設施&#xff0c;光伏景觀長廊頂上的光伏板不僅可以為周邊用電設備提供清潔電能&#xff0c;而且還能作為遮陽設施使用&#xff0c;為人們提供一個美麗又實用的休閑娛樂空間。 光伏景觀長廊建設對打造美麗鄉…

開發系統準備與開發環境配置總結

開發前系統配置及環境搭建 系統配置0 Github打不開、速度慢怎么辦1 WSL、Linux、Ubuntu、Docker都是什么鬼2 在Windows下安裝WSL和Ubuntu3 配置MySQL4 配置Redis并啟動服務5 Docker&#xff08;Windows和Ubuntu下&#xff09;6 Nginx 系統配置 你好&#xff01; 這是你第一次使…

uniapp 添加loading

在uniapp中添加loading可以使用uni的API uni.showLoading 方法。以下是一個簡單的示例代碼 // 顯示loading uni.showLoading({title: 加載中 });// 假設這里是異步操作&#xff0c;比如網絡請求 setTimeout(function () {// 隱藏loadinguni.hideLoading(); }, 2000);

C++(九)

前言&#xff1a; 本文主要講述運算符的優先順序。 一&#xff0c;運算符的優先級。 請看以下表達式&#xff1a; a32*5 運算結果為&#xff1a;13. 可以看到&#xff0c;在此代碼中&#xff0c;先運行了2*5的結果&#xff0c;在此基礎上在進行3操作&#xff0c;因此結果…

Android 拍照(有無存儲權限兩種方案,兼容Q及以上版本)

在某些行業&#xff0c;APP可能被禁止使用存儲權限&#xff0c;或公司在寫SDK功能&#xff0c;不方便獲取權限 所以需要有 無存儲權限拍照方案。這里兩種方案都列出里。 對于寫入權限&#xff0c;在高版本中&#xff0c;已經廢棄&#xff0c; 不可用文件寫入讀取權限&#xf…

【Altium Designer 】AD如何使用嘉立創元器件的3D封裝

1.下載3D封裝 以STM32F407VGT6為例&#xff0c;進入嘉立創商城網站&#xff0c;找到需要的元器件封裝 復制編號&#xff0c;打開嘉立創EDA&#xff0c;編譯器選擇專業版&#xff0c;新建工程&#xff0c;點擊PCB1 復制編號在搜索框中&#xff0c;點擊搜索&#xff0c;然后放置…

爬蟲運行后數據如何存儲?

爬蟲運行后獲取的數據可以存儲在多種不同的存儲系統中&#xff0c;具體選擇取決于數據的規模、查詢需求以及應用場景。以下是一些常見的數據存儲方法&#xff1a; 1. 文件系統 對于小型項目或臨時數據存儲&#xff0c;可以直接將數據保存到本地文件中。常見的文件格式包括&…

【機器學習】機器學習的基本分類-監督學習-梯度提升樹(Gradient Boosting Decision Tree, GBDT)

梯度提升樹是一種基于**梯度提升&#xff08;Gradient Boosting&#xff09;**框架的機器學習算法&#xff0c;通過構建多個決策樹并利用每棵樹擬合前一棵樹的殘差來逐步優化模型。 1. 核心思想 Boosting&#xff1a;通過逐步調整模型&#xff0c;使后續的模型重點學習前一階段…