zoukankan      html  css  js  c++  java
  • LeetCode 123 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).

    思路:本人脑子比較笨,思路比較冷门,并且效率高。

    时间复杂度最大为O(n^2),最小为为O(n),并不固定,空间复杂度为O(n)。时间复杂度为什么不固定,下文再说。注意如果是分为两次购买,则第一次卖出而第二次买入之间的时间内。股票必然下跌,否则就不须要分两次购买了。如果他第一次是从a天购入,第b天卖出;第二次购买是从第c天购入。

    则从第b天至第c天之间至少股票价格下跌一次,甚至连续下跌,所以我们仅仅须要找sub[i]<0的地方断开。分两次购买试试。所以当股票价格2i天上升。第2i+1天下降,或着第2i天下降。第2i+1天上升时。时间复杂度度为O(n^2)

    1.用一个数组sub[n-1]。(n为股票价格的天数)来存储当天与前一天股票的差价,即sub[i]=prices[i+1]-prices[i],从而将该题转化为一个或者两个最大子序列和的问题。

    2.当股票从第2天到第m天一直下跌时。而第m+1天股票价格上涨,则将sub[0...m-1]置为0。当股票在k天上涨。而从从第k+1天到第n一直跌,则将sub[k+1....n]置为0(本步骤不过为了优化,非必须)

    3.计算出仅仅购买一次的最大收益,与全部的当sub[i]<0时(这种i有可能不止一个),分两次购买的收益做比較。取最大值就可以。

    版本号1。用数组,快一些

    public class Solution {
    	public int maxsum(int[] num,int start,int end) {
    		int sum = 0;
    		int max = Integer.MIN_VALUE;
    		for (int i = start; i <=end; i++) {
    			sum += num[i];
    			if (max < sum) {
    				max = sum;
    			}
    			if (sum <= 0) {
    				sum = 0;
    			}
    		}
    		return max>>0?max:0;
    	}
    	public int maxProfit(int[] prices) {
    		if (prices.length == 0 || prices.length == 1)
    			return 0;
    		int[] sub = new int[prices.length - 1];
    		boolean flag=false;
    		for (int i = 0; i < sub.length; i++){
    			if(prices[i+1]-prices[i]>=0||flag){
    				flag=true;
    			    sub[i] = prices[i + 1] - prices[i];
    			}else{
    				sub[i]=0;
    			}
    		}
    		for (int i = sub.length-1; 0 <= i; i--){
    			if(prices[i+1]-prices[i]<0){
    			    sub[i] = 0;
    			}else{
    				break;
    			}
    		}
    		int result=maxsum(sub,0,sub.length-1);
    		for (int i=0;i<sub.length;i++){
    			if(sub[i]<0){
    				int temp=maxsum(sub,0,i-1)+maxsum(sub,i+1,sub.length-1);
    				result=result>temp?result:temp;
    			}
    		}
    
    		return result;
    	}
    }

    版本号2,使用ArrayList,当股票从一開始持续下跌,或着从某时间到结束一直下跌。则删除这些sub值。

    import java.util.ArrayList;
    
    public class Solution {
        public int maxsum(ArrayList<Integer> num,int start,int end) {
    		int sum = 0;
    		int max = Integer.MIN_VALUE;
    		for (int i = start; i <=end; i++) {
    			sum += num.get(i);
    			if (max < sum) max = sum;
    			if (sum <= 0) sum = 0;
    		}
    		return max>0?max:0;
    	}
    
    	public int maxProfit(int[] prices) {
    		if (prices.length==0||prices.length==1) return 0;
    		
    		ArrayList<Integer>  sub = new ArrayList<Integer>();
    		boolean flag=false;
    		
    		for (int i = 0; i < prices.length-1; i++){
    			if(prices[i+1]-prices[i]>=0||flag){
    				flag=true;
    			    sub.add(prices[i + 1] - prices[i]);
    			}	
    		}
    		for (int i = prices.length-2; 0 <= i; i--){
    			if(!sub.isEmpty()&&prices[i+1]-prices[i]<0) sub.remove(sub.size()-1);
    			else break;	
    		}
    		
    		if(sub.size()==0) return 0;
    		
    		int result=maxsum(sub,0,sub.size()-1);
    		for (int i=0;i<sub.size();i++){
    			if(sub.get(i)<0){
    				int temp=maxsum(sub,0,i-1)+maxsum(sub,i+1,sub.size()-1);
    				result=result>temp?result:temp;
    			}
    		}
    		
    		return result;
    	}
    }


    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    图论————拓扑排序
    状态压缩DP:蒙德里安的梦想
    差分+贪心:IncDec序列
    三目运算符
    贪心+高精度:国王游戏
    图论——最小生成树:Prim算法及优化、Kruskal算法,及时间复杂度比较
    图论——Floyd算法拓展及其动规本质
    图论——最短路:Floyd,Dijkstra,Bellman-Ford,SPFA算法及最小环问题
    贪心+DFS:引水入城
    网站移动版本开发踩坑实录一
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4725401.html
Copyright © 2011-2022 走看看