best-time-to-buy-and-sell-stock(购买并抛售股票的最佳时机)

题目1

(1)题目:假设你有一个数组,其中第i个元素是第i天给定股票的价格。
如果您只允许完成至多一笔交易(即买入一只股票并出售一只股票),则设计一种算法以找到最大利润。
(2)分析:分别计算第1天,第2天,...,第n-1天出售股票时的最大利润,再得出总的最大利润。
(3)代码:

代码1:

public class Solution {
    public int maxProfit(int[] prices) {
        if(prices==null || prices.length<=1) return 0;
        int n=prices.length;
        int max=0;
        for(int i=1;i<n;i++){
            for(int j=0;j<i;j++){//第i+1天出售股票
                max=Math.max(max,prices[i]-prices[j]);
            }
        }
        return max;
    }
}

代码2:保存每个最小值点,更新维护该值后面较大值和最小值的差
来自牛客网

public class Solution {
    public int maxProfit(int[] prices) {
        if(prices==null||prices.length==0){
            return 0;
        }
        int max=0;
        int min=prices[0];
        for(int i=0;i<prices.length;i++){
            min = Math.min(min,prices[i]);
            max=Math.max(max,prices[i]-min);
        }
        return max;
    }
}

题目2

(1)题目:假设你有一个数组,其中第i个元素是第i天给定股票的价格。设计一个算法来找到最大的利润。 您最多可以完成两笔交易。
注意:您不可以同时进行多笔交易(即您必须在再次购买之前出售股票)。
(2)分析:假设第i天为第一次出售股票的时间,计算第0天到第i天的最大利润;再分析第i+1天到第n-1天购买和出售股票的最大利润(当然这段时间内也可以没有交易)。最大利润为两者之和。
(3)代码:

代码1:

public class Solution {

    public int maxProfit(int[] prices) {
        if(prices==null || prices.length==0) return 0;
        return maxProfit(prices,0,prices.length-1);
    }

    public int maxProfit(int [] array,int start,int end){
        if(start>=end) return 0;
        int max=0;
        for(int i=start+1;i<=end;i++){
            max=Math.max(max,maxProfit1(array,start,i)+maxProfit2(array,i+1,end));
        }
        return max;
    }

    public int maxProfit1(int [] array,int start,int end){//计算第i天出售股票时的最大利润
        if(start>=end) return 0;
        int max=0;
        for(int i=start;i<end;i++){
            max=Math.max(max,array[end]-array[i]);
        }
        return max;
    }

    public int maxProfit2(int [] array,int start,int end){//计算第i+1到第n天购买和出售股票的最大利润
        if(start>=end) return 0;
        int max=0;
        for(int i=start;i<end;i++){
            for(int j=i+1;j<=end;j++){
                max=Math.max(max,array[j]-array[i]);
            }
        }
        return max;
    }
}

代码2:来自牛客网

/**
    * 分别计算出i之前和之后的最大利润pre[i],post[i]
    * 再以i为分割求出两次交易的最大利润(在i处可能卖出再买入,相当于就一次交易)
    * 空间换时间,时间复杂度O(n),空间复杂度O(n)
    * @param prices
    * @return
    */
   public int maxProfit(int[] prices) {
       if(prices==null||prices.length<2) return 0;
       int[]pre=new int[prices.length];
       int []post=new int[prices.length];
       int min=prices[0];
       for(int i=1;i<prices.length;i++){
           min=Math.min(min,prices[i]);
           pre[i]=Math.max(pre[i-1],prices[i]-min);
       }
       int max=prices[prices.length-1];
       for(int i=prices.length-2;i>=0;i--){
           max=Math.max(max,prices[i]);
           post[i]=Math.max(post[i+1],max-prices[i]);
       }
       int maxProfit=0;
       for(int i=0;i<prices.length;i++){
           maxProfit=Math.max(maxProfit,pre[i]+post[i]);
       }
       return  maxProfit;
   }

题目3

 (1)题目:假设你有一个数组,其中第i个元素是第i天给定股票的价格。设计一个算法来找到最大的利润。 您可以根据需要完成尽可能多的交易(即多次买入和卖出一次股票)。 但是,您不得同时进行多笔交易(即您必须在再次购买之前出售股票)。
 (2)分析:假设第i天为第一次出售股票的时间,计算出第0天到第i天这段时间的最大利润。然后再计算第i+1天到第n天这段时间的最大利润,这是一个递归求解的过程。
(3)代码:

代码1:该算法因为用到了递归,导致时间复杂度太大。

public class Solution {

    public int maxProfit(int[] prices) {
        if(prices==null || prices.length<=1) return 0;
        return maxProfit(prices,0,prices.length-1);
    }

    public int maxProfit(int [] array,int start,int end){
        if(start>=end) return 0;
        int max=0;
        for(int i=start+1;i<=end;i++){
            max=Math.max(max,maxProfit1(array,start,i)+maxProfit(array,i+1,end));
        }
        return max;
    }

    public int maxProfit1(int [] array,int start,int end){
        if(start>=end) return 0;
        int max=0;
        for(int i=start;i<end;i++){
            max=Math.max(max,array[end]-array[i]);
        }
        return max;
    }

}

代码2:来自牛客网

class Solution {
public:
    int maxProfit(vector<int> &prices) {
        //本题由于允许多次交易(每次必须先卖出再买进),所以不好用爆搜
        //分析可知,要想利益最大化,就应该每次在波谷买进,波峰卖出,这样利益最大,操作次数最少。
        //波峰减波谷等于波峰到波谷的元素依次相减的和
        //应该是使用动态规划来做可能比较简洁,个人觉得。

        int len = prices.size();
        vector<int> change(len,0);
        int maxPro=0;
        for(int i=1;i<len;i++){
            change[i]=prices[i]-prices[i-1];  //记录所有长和跌的情况
            if(change[i]>0)maxPro += change[i];  //累加所有长幅,即为最大收益
        }
        return maxPro;
    }
};

题目1来自牛客网leetcode
题目2来自牛客网leetcode
题目3来自牛客网leetcode

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值