(包含变种)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;  
    }
}
复制代码
相关文章
相关标签/搜索