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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

leetcode 121 股票买卖问题系列

發布時間:2025/3/8 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 leetcode 121 股票买卖问题系列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

描述:

給一些列數字,表示每條股票的價格,如果可以買賣一次(不能同一天買和賣),求最大利益(即差最大)。

其他三道問題是,如果能買賣無限次,買賣兩次,買賣k次。

題一:

實質是求后面一個數減前一個數的最大差值。

維護一個最小值,和當前最大值。只需遍歷一次,空間也是常數。

int maxProfit(vector<int>& prices) {if (prices.size() < 1)return 0;int min_ = prices[0];int ret = 0;for (int i = 1; i < prices.size(); i++) {ret = max(ret, prices[i] - min_);min_ = min(min_, prices[i]);}return ret; }

題二:

只要是后一個數比前一個大,都增。

int maxProfit(vector<int>& prices) {if (prices.size() < 1)return 0;int ret = 0;for (int i = 0; i < prices.size() - 1; i++) {ret += max(prices[i + 1] - prices[i], 0);}return ret; }

題三:

可進行兩次操作。

其中一個思路,可以關注分界點,可以枚舉分界點,求左右兩邊的最優操作,在LeetCode會超時,顯然,復雜度n^2。

思考下優化,我們可以計算每個點的最大值,左邊不用重復計算,每次分界點往左移,都像題一那樣計算最大值即可;

      而右邊,其實可以反向計算一遍,但是,右邊改成求最小值。

      最后加起來即可。

int maxProfit(vector<int>& prices) {int size = prices.size();if (size < 1)return 0;int* left = new int[size]{0};int* right = new int[size]{0};int ret = 0;int lmin = prices[0];int lmax = 0;for (int i = 1; i < size; i++) {lmax = max(lmax, prices[i] - lmin);left[i] = lmax;lmin = min(lmin, prices[i]);}int rmin = 0;int rmax = prices[size - 1];for (int i = size - 1; i >= 0; i--) {rmin = min(rmin, prices[i] - rmax);right[i] = -rmin;rmax = max(rmax, prices[i]);}for (int i = 0; i < size - 1; i++) {ret = max(ret, left[i] + right[i + 1]);}return max(ret, left[size - 1]); }

思路二:

int maxProfit(vector<int>& prices) {int n = prices.size();if(n==0) return 0;int sell1 = 0, sell2 = 0, buy1 = INT_MIN, buy2 = INT_MIN;for(int i =0; i<n; i++){buy1 = max(buy1, -prices[i]);sell1 = max(sell1, prices[i]+buy1);buy2 = max(buy2, sell1-prices[i]);sell2 = max(sell2, prices[i]+buy2);} return sell2; }

題四:

動態規劃:

其中diff表示今天和昨天的差。

global[i][j] = max(local[i][j], global[i-1][j])

local[i][j] = max(global[i-1][j-1] + max(diff,0), local[i-1][j] + diff)

?

local[i][j]表示最后一次賣出在今天的最大利益,局部最優。

global[i][j]表示全局最優。

第一條式子:要么在今天賣出最優,要么前一天的全局最優。

第二條式子:前者為之前的全局最優加上最后一次交易在今天。

        注意diff,我們要的是不大于j的交易次數;

        如果i - 1天還持有,則i天賣出,共j - 1次操作;如果i-1天不持有,則i - 1天買入,i天賣出,共j次操作。

      后者為i - 1天賣出加上今天diff,表示i - 1天還持有,加上今天的。

int maxProfit(int k, vector<int>& prices) { if (prices.size() < 2) return 0; int days = prices.size(); if (k >= days) return maxProfit2(prices);auto local = vector<vector<int> >(days, vector<int>(k + 1));auto global = vector<vector<int> >(days, vector<int>(k + 1));for (int i = 1; i < days ; i++) {int diff = prices[i] - prices[i - 1]; for (int j = 1; j <= k; j++) { local[i][j] = max(global[i - 1][j - 1], local[i - 1][j] + diff); global[i][j] = max(global[i - 1][j], local[i][j]); } } return global[days - 1][k]; } int maxProfit2(vector<int>& prices) { int maxProfit = 0; for (int i = 1; i < prices.size(); i++) { if (prices[i] > prices[i - 1]) { maxProfit += prices[i] - prices[i - 1]; } } return maxProfit; }

類似題三的做法:

int maxProfit(int k, vector<int>& prices) {int n = prices.size();if(k>n/2){int buy = INT_MIN, sell = 0;for(int i=0; i<n; i++){buy = max(buy, sell-prices[i]);sell = max(sell, buy+prices[i]);}return sell;}vector<int> sell(k+1, 0);vector<int> buy(k+1, 0);for(int i=0; i<=k; i++) buy[i] = INT_MIN;for(int i=0; i<n; i++){for(int j=1; j<k+1; j++){buy[j] = max(buy[j], sell[j-1]-prices[i]);sell[j] = max(sell[j], buy[j]+prices[i]);}}return sell[k]; }

?

轉載于:https://www.cnblogs.com/willaty/p/8304914.html

總結

以上是生活随笔為你收集整理的leetcode 121 股票买卖问题系列的全部內容,希望文章能夠幫你解決所遇到的問題。

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