买卖股票最佳时机I
暴力解法(超時)
暴力,找最優間距
時間復雜度:O(n^2) 空間復雜度:O(1) class Solution { public:int maxProfit(vector<int>& prices) {int profit=0;for(int ii=0;ii<prices.size();ii++){//int buy=prices[ii];for(int jj=ii+1;jj<prices.size();jj++){// int sale=prices[jj];// if(sale>=buy){// profit=max(profit,sale-buy);// }profit=max(profit,prices[jj]-prices[ii]);}}return profit;} };貪心解法
因為股票就買賣一次,那么貪心的想法很自然就是取最左最小值,取最右最大值,那么得到的差值就是最大利潤。
class Solution { public:int maxProfit(vector<int>& prices) {int profit=0;int left=INT_MAX;for(int ii=0;ii<prices.size();ii++){left=min(left,prices[ii]); // 取最左最小價格profit=max(prices[ii]-left,profit);// 直接取最大區間利潤}return profit;} }; 時間復雜度:O(n) 空間復雜度:O(1)動態規劃
確定dp數組(dp table)以及下標的含義
dp[i][0] 表示第i天持有股票所得最多現金
一開始現金是0,那么加入第i天買入股票現金就是 -prices[i], 這是一個負數。
dp[i][1] 表示第i天不持有股票所得最多現金
注意這里說的是“持有”,“持有”不代表就是當天“買入”!也有可能是昨天就買入了,今天保持持有的狀態
確定遞推公式
記住股票我們只交易一次。一、如果第i天持有股票即dp[i][0], 那么可以由兩個狀態推出來
1、第i-1天就持有股票,那么就保持現狀,所得現金就是昨天持有股票的所得現金 即:dp[i - 1][0]。
2、第i天買入股票,所得現金就是買入今天的股票后所得現金即:-prices[i]
那么dp[i][0]應該選所得現金最大的,所以
二、如果第i## 天不持有股票即dp[i][1], 也可以由兩個狀態推出來
1、第i-1天就不持有股票,那么就保持現狀,所得現金就是昨天不持有股票的所得現金 即:dp[i - 1][1]
2、第i天賣出股票,所得現金就是按照今天股票佳價格賣出后所得現金即:prices[i] + dp[i - 1][0]
同樣dp[i][1]取最大的,
dp數組如何初始化
由遞推公式 dp[i][0] = max(dp[i - 1][0], -prices[i]); 和 dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);可以看出
其基礎都是要從dp[0][0]和dp[0][1]推導出來。
那么dp[0][0]表示第0天持有股票,此時的持有股票就一定是買入股票了,因為不可能有前一天推出來,所以dp[0][0] -= prices[0];
dp[0][1]表示第0天不持有股票,不持有股票那么現金就是0,所以dp[0][1] = 0;
確定遍歷順序
從遞推公式可以看出dp[i]都是有dp[i - 1]推導出來的,那么一定是從前向后遍歷。
舉例推導dp數組
以示例1,輸入:[7,1,5,3,6,4]為例,dp數組狀態如下:
總結
- 上一篇: 还要打家劫舍
- 下一篇: 买卖股票的最佳时机II