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

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