解题思路:可能是我的理解力有限,但总感觉题目描述的理解起来费劲。
题目抽象一下,就是给定一个数组,按照某种规则找出这个数组的最大值。规则:最多取两个数,然后丢到一个数,看看手中的数的最大值。卖出为+,买入为-。
利用动态规划来考虑:从数组的左侧到右侧遍历,计算最大值保存成数组,同理从右侧到左侧,计算最大值保存成数组。找两个数组对应值得和,找出最大值。
1、从左到右扫描一遍,dpl[i]表示到i位置最大的收益;计算最大收益:用minIndex取得最大收益时较小值的位置。
1.1若prices[i+1] > prices[i],则dpl[i+1] 是 dpl[i]或者prices[i+1]-prices[minIndex]的最大值。
1.2若prices[i+1] < prices[i],则prices[i+1]-prices[minIndex]一定比dpl[i]要小,故dpl[i+1] = dp[i]。
同时,判断当前的prices[i]是否小于prices[minIndex],如果小于则修改minIndex的值。
2、同理,从右到左扫描,并记录dpr[i]的所有值。
/**
* 题目描述 风口之下,猪都能飞。当今中国股市牛市,真可谓“错过等七年”。
* 给你一个回顾历史的机会,已知一支股票连续n天的价格走势,以长度为n的整数数组表示,数组中第i个元素(prices[i])代表该股票第i天的股价。
* 假设你一开始没有股票,但有至多两次买入1股而后卖出1股的机会,并且买入前一定要先保证手上没有股票。若两次交易机会都放弃,收益为0。
* 设计算法,计算你能获得的最大收益。 输入数值范围:2<=n<=100,0<=prices[i]<=100
* 示例1 输入
* 3,8,5,1,7,8
* 输出
* 12
* @author 崔洪振367
* @version 创建时间:2017年6月30日 下午11:06:29
* 解题思路:迷迷糊糊的。
*
*/
public class 风口的猪_中国牛市 {
/**
* 计算你能获得的最大收益
*
* @param prices Prices[i]即第i天的股价
* @return 整型
*/
public int calculateMax(int[] prices) {
int len = prices.length;
int[] dpl = new int[len];
dpl[0] = 0;
int minIndex = 0;//最小值的下标
//从左到右,求收益最大值放入dpl中
for(int i=1; i<len; i++){
if(prices[i] > prices[i-1]){
dpl[i] = Math.max(prices[i] - prices[minIndex], dpl[i-1]);//动态规划,利用前边的值填写后边的值
}else{
dpl[i] = dpl[i-1];
if(prices[i] < prices[minIndex]){
minIndex = i;
}
}
}
//从右到左,求收益最大值
int[] dpr = new int[len];
dpr[len-1] = 0;//最左端的初始值赋值为0
int maxIndex = len-1;//最大值的下标
for(int i=len-2; i>=0; i--){
if(prices[i] < prices[i+1]){
dpr[i] = Math.max(prices[maxIndex] - prices[i], dpr[i+1]);
}else {
dpr[i] = dpr[i+1];
if(prices[maxIndex] < prices[i]){
maxIndex = i;
}
}
}
//根据输入dpl和dpr求解整个过程的最大值。
//说白了,就是将一个数组分成两部分,然后求各部分的最大值,输出最大值。
int result = 0;
for(int i=0; i<len; i++){
result = Math.max(dpl[i]+dpr[i], result);
}
return result;
}
}