LeetCode Best Time to Buy and Sell Stock I & II & III & IV

LeetCode Best Time to Buy and Sell Stock

問題來源
LeetCode 121. Best Time to Buy and Sell Stock
LeetCode 122. Best Time to Buy and Sell Stock II
LeetCode 123. Best Time to Buy and Sell Stock III
LeetCode 188. Best Time to Buy and Sell Stock IV

問題描述 Best Time to Buy and Sell Stock I

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 (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.

Example 1:

Input: [7, 1, 5, 3, 6, 4]
Output: 5

max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price)

Example 2:
Input: [7, 6, 4, 3, 1]
Output: 0

In this case, no transaction is done, i.e. max profit = 0.

問題分析 Best Time to Buy and Sell Stock

這一系列的題是根據給定的貨物價格,設計買賣方案得到最大利潤。第一題比較簡單,限定了只能一次買賣。那麼所要達到的目的就如下圖了。
算法1

尋求最低價格和之後的最高價格。算法比較簡單。就是找前後的最大價格差。但是要限定最低價格要在最高價格之前。

代碼如下 Best Time to Buy and Sell Stock

public int maxProfit(int[] prices) {
    if(prices==null||prices.length<1){
        return 0;
    }
    int minIndex = 0;
    int maxIndex = 0;
    int res  = 0;
     for (int i = 0; i < prices.length; i++) {
        if(prices[i]<prices[minIndex]){
            res=Math.max(prices[maxIndex]-prices[minIndex],res);
            minIndex=i;
            maxIndex=i;
        }
        if(prices[i]>=prices[maxIndex]){
            maxIndex=i;
        }
    }
    return Math.max(prices[maxIndex]-prices[minIndex],res);
}

問題描述 Best Time to Buy and Sell Stock II

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

Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

問題分析 Best Time to Buy and Sell Stock II

這道題與上一道題不同的就在於這一道題不限定買賣次數,所以說只要買入價格低於賣出價格就可以進行買賣。也就是隻有要利潤就可以買賣一次。但是題目中限定一天只能進行一次操作。代碼也比較簡單

代碼如下 Best Time to Buy and Sell Stock II


public int maxProfit(int[] prices) {
    int maxIndex=0;
    int minIndex=0;
    int res =0;
    boolean state =false;
    int i =0;
    for(;i<prices.length-1;i++){
        if(!state &&prices[i]<prices[i+1]){
            minIndex=i;
            state=true;
        }
        if(state&&prices[i]>prices[i+1]){
            maxIndex=i;
            res+=prices[maxIndex]-prices[minIndex];
            state=false;
        }
    }
    if(state){
        res+=Math.max(0,prices[i]-prices[minIndex]);
    }
    return res;
}

一開始沒有想太明白,後來經過優化的代碼其實就幾行可以解決這個問題

int maxProfit(int[] prices){
    int res = 0;
    for (int i = 1; i < prices.length; ++i) {
        if (prices[i] - prices[i - 1] > 0) {
            res += prices[i] - prices[i - 1];
        }
    }
    return res;
}

從這裏就能感受到如果把問題分析明白了,代碼量真的可以減少很多。

問題描述 Best Time to Buy and Sell Stock III

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

Design an algorithm to find the maximum profit. You may complete at most two transactions.

Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

問題分析 Best Time to Buy and Sell Stock III

這道題限定條件比較嚴格了,就是可以進行兩次買賣。雖然只比原始題目多一次買賣,但是Hard難度的標籤能夠看出來這道題沒有那麼簡單。

可以這麼理解,在進行第一次買賣的時候,之前沒有任何買賣。在進行第二次買賣的時候,之前進行了一次買賣。那麼我們先計算第一次到某個時間進行了第一次買賣的時候的利潤,然後在計算第二次買賣的利潤。

也就是滿足遞推公式,具體描述參見下圖。
這裏寫圖片描述

代碼如下 Best Time to Buy and Sell Stock III

public int maxProfit(int[] prices) {
    if (prices == null) return 0;
    int[] dpG = new int[3];
    int[] dpL = new int[3];
    for (int i = 0; i < prices.length - 1; i++) {
        int delta = prices[i + 1] - prices[i];
        for (int j = 2; j >= 1; j--) {
            dpL[j] = Math.max(dpG[j - 1] + (delta < 0 ? 0 : delta), dpL[j] + delta);
            dpG[j] = Math.max(dpL[j], dpG[j]);
        }
    }
    return dpG[2];
}

問題描述

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

Design an algorithm to find the maximum profit. You may complete at most k transactions.

Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

問題分析 Best Time to Buy and Sell Stock IV

這道題是上一個問題的拓展,給定的K代表K次交易。那麼可以按照上一道題的思路進行拓展,將變量數組的長度變爲K+1;
但是這道題需要注意,如果給定的K大於了交易日期,那麼就可以看作是第二題了,不限制交易次數(因爲可供選擇的交易次數大於最大交易次數)
所以這道題應該是2和3的結合。代碼就直接列出了。

代碼如下 Best Time to Buy and Sell Stock IV

public int maxProfit(int k, int[] prices) {
    if(prices==null||prices.length<1||k<1) return 0;
    if(k>=prices.length) return maxProfit2(prices);
    int [] dpG = new int[k+1];
    int [] dpL = new int[k+1];
    for (int i = 0; i < prices.length-1; i++) {
        int delta = prices[i + 1] - prices[i];
        for (int j = k; j >=1 ; j--) {
            dpL[j] = Math.max(dpG[j - 1] + (delta < 0 ? 0 : delta), dpL[j] + delta);
            dpG[j] = Math.max(dpL[j], dpG[j]);
        }
    }
    return  dpG[k];
}
int maxProfit2(int[] prices){
    int res = 0;
    for (int i = 1; i < prices.length; ++i) {
        if (prices[i] - prices[i - 1] > 0) {
            res += prices[i] - prices[i - 1];
        }
    }
    return res;
}

第一次將LeetCode裏面的一個系列的題寫在一起,之前也遇到過一些樹的題,希望能夠把這些題總結起來,給自己加個油把。
LeetCode學習筆記持續更新

GitHub地址 https://github.com/yanqinghe/leetcode

CSDN博客地址 http://blog.csdn.net/yanqinghe123/article/category/7176678

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章