(包含變種)Best Time to Buy and Sell Stock 最佳買賣股票時機

初來乍到,請多多指教~!算法

121. Best Time to Buy and Sell Stock 最佳買賣股票時機

題目描述

假設您有一個數組,其中第i個元素是第i天給定股票的價格。數組

若是您只被容許完成最多一筆交易(即買入並賣出一股股票),請設計一個算法以找到最大利潤。bash

請注意,在購買以前不能出售股票。this

Example 1:spa

Input: [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 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
Explanation: In this case, no transaction is done, i.e. max profit = 0.
複製代碼

代碼實現

數組中第i個數字減去前面i-1個數字中的最小數字即爲從前i個股票價格變化中可獲得的最大收益。code

class Solution {
    public int maxProfit(int[] prices) {
        int maxPrice = 0;
        int minPrice = Integer.MAX_VALUE;
        for(int price: prices) {
            maxPrice = Math.max(maxPrice, price - minPrice);
            minPrice = Math.min(minPrice, price);
        }
        return maxPrice;
    }
}
複製代碼

動態規劃:ip

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

122. Best Time to Buy and Sell Stock II 買賣股票的最佳時機 Ⅱ

題目描述

假設您有一個數組,其中第 i 個元素是第 i 天給定股票的價格。it

設計算法以找到最大利潤。 您能夠根據須要完成儘量多的交易(即,屢次買入並賣出一股股票)。io

注意:您不得同時進行多筆交易(即,您必須在再次購買以前賣出股票)。

Example 1:

Input: [7,1,5,3,6,4]
Output: 7
Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4.
             Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3.
複製代碼

Example 2:

Input: [1,2,3,4,5]
Output: 4
Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
             Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
             engaging multiple transactions at the same time. You must sell before buying again.
複製代碼

Example 3:

Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.
複製代碼

思路與實現

貪心算法: 以上帝視角來看,假如咱們知道後一天的股票比今天的票價貴,那麼咱們就今天買入明天賣出。可是這個會違反同一天不能同時買賣的原則(不過題目並無限制),這題有點投機取巧的感受

class Solution {
    public int maxProfit(int[] prices) {
        int res = 0;
        int profit = 0;
        for (int i = 0; i < prices.length - 1; i++) {
            profit = prices[i + 1] - prices[i];
            if (profit > 0) {
                res += profit;
            }
        }
        return res;
    }
}
複製代碼

123. Best Time to Buy and Sell Stock III 買賣股票的最佳時間 Ⅲ

題目描述

假設您有一個數組,其中第i個元素是第i天給定股票的價格。

設計算法以找到最大利潤。 您最多能夠完成兩筆交易

注意:您不得同時進行多筆交易(即,您必須在再次購買以前賣出股票)。

題意:

  • 使用兩個區間,
  • 即不能同時持有兩支股票,

Example 1:

Input: [3,3,5,0,0,3,1,4]
Output: 6
Explanation: Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.
             Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 = 3.
複製代碼

Example 2:

Input: [1,2,3,4,5]
Output: 4
Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
             Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
             engaging multiple transactions at the same time. You must sell before buying again.
複製代碼

Example 3:

Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.
複製代碼

思路與實現

根據題目要求,最多進行兩次買賣股票,並且手中不能有2只股票,就是不能連續兩次買入操做。

因此,兩次交易必須是分佈在2各區間內,也就是動做爲:買入賣出,買入賣出。

進而,咱們能夠劃分爲2個區間[0,i]和[i,len-1],i能夠取0~len-1。

那麼兩次買賣的最大利潤爲:在兩個區間的最大利益和的最大利潤。

一次劃分的最大利益爲:Profit[i] = MaxProfit(區間[0,i]) + MaxProfit(區間[i,len-1]);

最終的最大利潤爲:MaxProfit(Profit[0], Profit[1], Profit[2], ... , Profit[len-1])。

動態規劃

class Solution {
    public int maxProfit(int[] prices) {  
        if(prices == null || prices.length <= 1){  
            return 0;  
        }  
        int len = prices.length;  
        int maxProfit = 0;  
        int min = prices[0];  
        int arrayA[] = new int[len];  
        
        for(int i=1;i<prices.length;i++){
            min=Math.min(min,prices[i]);
            arrayA[i]=Math.max(arrayA[i-1],prices[i]-min);
        }
        
        int max = prices[len-1];  
        int arrayB[] = new int[len];  
        for(int i = len-2; i >= 0; i--){
            max = Math.max(prices[i],max);
            arrayB[i] = Math.max(max-prices[i],arrayB[i+1]);
        }  
        
        for(int i = 0; i < len; i++){  
            maxProfit = Math.max(maxProfit,arrayA[i] + arrayB[i]);
        }  
        
        return maxProfit;  
    }
}
複製代碼
相關文章
相關標籤/搜索