Stock(買賣股票)

1. 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 (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.

記錄當(dāng)前最小的買進(jìn)價格,隨后進(jìn)行賣出,并且和當(dāng)前最大的獲利相比較,如果比當(dāng)前最大的還要大,則更新當(dāng)前最大值,否則繼續(xù)執(zhí)行,最后返回最大值。

class Solution {
    public int maxProfit(int[] prices) {
        if(prices.length <2)
            return 0;
        int max = 0;
        int minprice = prices[0];
        for(int i=0; i<prices.length; i++){
            if(prices[i]-minprice>max){
                max = prices[i]-minprice;
            }
            if(minprice>prices[i]){
                minprice = prices[i];
            }
        }        
        return max;
    }
}

2. 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).

可以無限次買賣股票,但是必須先賣了才能買新的,思路是從第二天開始,如果今日價格比昨天高,那么則可以昨日買入,今日賣出,而到了明日又可以重復(fù)該過程直到利潤最大值。

class Solution {
    public int maxProfit(int[] prices) {
        if(prices.length < 2){
            return 0;
        }
        int sum = 0;
        for(int i=1; i<prices.length; i++){
            if(prices[i-1]<prices[i]){
                sum += prices[i]-prices[i-1];
            }
        }
        return sum;
    }
}

3. 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).

第一種方法比較簡單,就是當(dāng)成兩個兩個stcokI 來求解,,即求[0,i],[i+1,n]兩個最大值之和。時間復(fù)雜度優(yōu)化后為O(n)。

class Solution {
    public int maxProfit(int[] prices) {
        if(prices.length < 2){
            return 0;
        }
        int[] startprices = new int[prices.length];
        int[] endprices = new int[prices.length];
        for(int i=0; i<prices.length; i++){
            startprices[i] = 0;
            endprices[i] = 0;
        }
        int minprices = prices[0];
        for(int i=1; i<prices.length; i++){
            startprices[i] = Math.max(startprices[i-1], prices[i]-minprices);
            minprices = Math.min(minprices, prices[i]);
        }
        
        int maxprices = prices[prices.length-1];
        for(int i=prices.length-2; i>=0; i--){
            endprices[i] = Math.max(endprices[i+1], maxprices-prices[i]);
            maxprices = Math.max(maxprices, prices[i]);
        }
        
        int max = 0;
        for(int i=0; i<prices.length; i++){
            max = Math.max(max, startprices[i]+endprices[i]);
        }
        return max;
    }
}

4. Best Time to Buy and Sell Stock IV

Say you have an array for which the *i*th
 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).
**Credits:**Special thanks to [@Freezen](https://oj.leetcode.com/discuss/user/Freezen) for adding this problem and creating all test cases.

這題使用動態(tài)規(guī)劃
我們定義local[i][j]為在到達(dá)第i天時最多可進(jìn)行j次交易并且最后一次交易在最后一天賣出的最大利潤,此為局部最優(yōu)。然后我們定義global[i][j]為在到達(dá)第i天時最多可進(jìn)行j次交易的最大利潤,此為全局最優(yōu)。它們的遞推式為:

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

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

其中局部最優(yōu)值是比較前一天并少交易一次的全局最優(yōu)加上大于0的差值,和前一天的局部最優(yōu)加上差值中取較大值,而全局最優(yōu)比較局部最優(yōu)和前一天的全局最優(yōu)。
如果k的值遠(yuǎn)大于prices的天數(shù),比如k是好幾百萬,而prices的天數(shù)就為若干天的話,上面的DP解法就非常的沒有效率,應(yīng)該直接用[Best Time to Buy and Sell Stock II 的方法來求解。

class Solution {
    public int maxProfit(int k, int[] prices) {
        int n = prices.length;
        if(n<2){
            return 0;
        }
        if(k>=n){
            return maxstock(prices);
        }
        int[][] g = new int[n][k+1];
        int[][] l = new int[n][k+1];
        for(int i=1; i<n;i++){
            int diff = prices[i]-prices[i-1];
            for(int j=1;j<k+1;j++){
                l[i][j] = Math.max(g[i-1][j-1]+Math.max(diff, 0), l[i-1][j]+diff);
                g[i][j] = Math.max(g[i-1][j], l[i][j]);
            }
        }
        return g[n-1][k];
        
    }
    
    public int maxstock(int[] prices){
         if(prices.length < 2){
            return 0;
        }
        int sum = 0;
        for(int i=1; i<prices.length; i++){
            if(prices[i-1]<prices[i]){
                sum += prices[i]-prices[i-1];
            }
        }
        return sum;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容