首页 > 代码库 > LeetCode——Best Time to Buy and Sell Stock II

LeetCode——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).

原题链接:https://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/

题目:如果你有一个数组,当中的第 i 个元素代表给定的第 i 天的股票价格。

设计一个算法找出最大的利润。

你能够完毕多个交易(如,买一和卖一股票 多次)。可是,你不能同一时候进行多个交易(如,你必须在新买入之前卖出)。

思路:能够理解成求随意多个二元序列之差 之和 的最大值,当中每对序列之差需为正数。相应的索引要减号之前的大于减号之后的。

比方:[1,2,4,3,5,7,6]这样一个数组。

能够这样计算:

2 - 1 = 1

5 - 4 = 1

7 - 3 = 4

1 + 1 + 4 = 6

也能够这样计算:

7 - 1 = 6

6 - 2 = 4

5 - 3 = 2

6 + 4 + 2 = 12

由上的样例能够看出,利润的最大值应该是这样;依次用后序的最大值减去前面的最小值 之和。分析到这里,也就能够利用上一题的做法了,上一题是找到一次交易中利润最大的,我们要求的是多次交易的最大利润,能够转化为每次都是最大利润,最后汇总。

详细做法就是。每次计算完最大利润之后。将这个最大利润相应的序列从数组中删除。再来计算下一次的最大利润……。

写的有点复杂了,计算结果应该是错的,由于并没有依照时间序列的顺序来做,即后一次买入的位置必须在前一次卖出之后。

public class BestTimetoBuyandSellStockII {
	public static void main(String[] args) {
		delete(new int[]{2,1},0);
		int ret = maxProfit(new int[]{1,2,4,3,5,7,6});
		System.out.println(ret);
	}
	public static int maxProfit(int[] prices){
		int len = prices.length;
		if(len <= 1)
			return 0;
		int max = 0;
		T t = max(prices);
		while(true){
			max += t.max;
			if(t.ary.length <= 1)
				break;
			if(t.ary.length == 2){
				if(t.ary[1] < t.ary[0])
					break;
				else
					max += t.ary[1] - t.ary[0];
				break;
			}
			t = max(t.ary);
		}
		return max;
	}
	//每次的最大利润
	public static T max(int[] prices){
		int len = prices.length;
		if(len <= 1)
			return null;
		int min = prices[0],max = 0,largest = 0;
		for(int i=1;i<len;i++){
			int profit = prices[i] - min;
			if(max < profit){
				max = profit;
				largest = prices[i];
			}
			if(min > prices[i])
				min = prices[i];
		}
		System.out.println("min = " + min + "\tlargest = " + largest + "\tmax = "+ max);
		int[] a = delete(prices,min);
		int[] b = delete(a,largest);
		return new T(max,b);
	} 
	//删除数组中的某个元素
	public static int[] delete(int[] prices,int price){
		int len = prices.length;
		if(len <= 0 || price <= 0)
			return null;
		int[] ret = new int[len - 1];
		int index = 0;
		for(int i=0;i<len;i++){
			if(prices[i] == price){
				index = i;
				break;
			}
			ret[i] = prices[i];
		}
		for(int i=index;i<ret.length;i++){
			ret[i] = prices[i+1];
		}
		return ret;
	}
	static class T {
		int max;
		int[] ary;
		public T(int max,int[] ary){
			this.max = max;
			this.ary = ary;
		}
	}
}
更简单的解法是 借鉴了这位网友[1]的思路 ; 从头到尾扫描prices,假设i比i-1大,那么price[i] – price[i-1]就能够计入最后的收益中。这样扫描一次O(n)就能够获得最大收益了。

	public static int maxProfit(int[] prices){
		int len = prices.length;
		if(len <= 1)
			return 0;
		int sum = 0;
		for(int i=1;i<len;i++){
			int profit = prices[i] - prices[i - 1];
			if(profit > 0)
				sum += profit;
		}
		return sum;
	}

[1] reference : http://blog.unieagle.net/2012/12/04/leetcode%E9%A2%98%E7%9B%AE%EF%BC%9Abest-time-to-buy-and-sell-stock-ii/

LeetCode——Best Time to Buy and Sell Stock II