题目描述
一个一维数组代表着股票的价值,可以执行两个操作,一个是买操作,一个是卖操作,如何能让利润最大化,
说白了就是如何让差价最大话,在卖股票之前必须进行股票的购买操作,每个操作只最多只能执行一次。
Example 1:
Input: [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
Not 7-1 = 6, as selling price needs to be larger than buying price.
在第二天价格为1的时候买进来,在第五天价格为6元的时候卖出,可以赚到5元的价格差,
Example 2:
Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.
这种情况下股票价格是一直在下降的
思路一:常规方法
不采用动态规划算法解决,每个位置处往前找一个最小值作为股票的购买日子去,把第i个元素作为卖出的日子,
在第i个元素之前0到i-1个元素之间找出最小的元素min_price, 如何min_price
public int solution_1(int [] prices){
if(prices.length==0||prices==null||prices.length==1) return 0;
int n = prices.length;
int max_price=0;
for(int i=1;i<n;i++){
int min = prices[0];
for(int j=0;j<i;++j){
if(prices[j]<min)
min = prices[j];
}
if(min<prices[i])
max_price= Math.max(prices[i]-min,max_price);
}
return max_price;
}
复杂度
时间负责度为O(N),空间负责度为O(1)
思路二:贪心算法
基本思路跟上面的步骤一样,就是如何查找i之前的最小元素这里改变一下做法,不用每次都回溯回去,导致时间复杂度增加一个纬度O(N)
每处理一个元素就记录一下最小值,即可,逐步处理逐步记录最小值,
public int solution_2(int[] prices) {
if(prices.length<2) return 0;
int profit = 0;//差价,也就是利润的问题
//代表最小位置信息
int min = prices[0];
for(int i=1;i<prices.length;++i){
profit = Math.max(profit,prices[i]-min);
//记录最小的位置,更新最小值操作
min = Math.min(min,prices[i]);
}
return profit;
}
思路三:Kadane’s Algorithm
maximum subarray problem同样类似的问题
最大子序列和问题
同样在这里面
解决办法
public int maxProfit(int[] prices) {
int maxCur = 0, maxSoFar = 0;
for(int i = 1; i < prices.length; i++) {
maxCur = Math.max(0, maxCur += prices[i] - prices[i-1]);
maxSoFar = Math.max(maxCur, maxSoFar);
}
return maxSoFar;
}
表示以该元素为卖出日能获取到的最大利润
maxCur = current maximum value
表示在该元素处卖出去能获取得到的最大利润
maxSoFar = maximum value found so far