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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值