最大和连续子序列系列
一. 简单题目(求数组中最大和连续子序列)
思路:(前i个数的和+当前数)是否大于当前数,大于则为前i个数的和+当前数,否则为当前数
// // main.cpp // 最大连续子序列和 // // Created by jzc on 2018/4/24. // Copyright © 2018年 jzc. All rights reserved. // #include <iostream> using namespace std; int main() { int a[9] = {-2,1,-3,4,-1,2,1,-5,4}; int sum[9]; sum[0] = a[0]; int k ; for(int i =1;i<9;i++){ if(sum[i-1]+a[i]>a[i]) sum[i] = sum[i-1]+a[i]; else { sum[i] = a[i]; k = i; } } int max = a[0]; for(int i =0;i<9;i++) { if(sum[i]>max) { max = sum[i]; } } cout<<"子序列最大和:"<<max<<endl; int count =0; cout<<"子序列为:"; while(count!=max) { cout<<a[k]<<" "; count+=a[k]; k++; } cout<<endl; return 0; }
二. 进阶连续子序列:
leetcode121: 题目大概意思是:一串数组,第i天对应的股票为a[i], 第i天买股票,第j天卖股票,收益为a[j]-a[i](卖股票的日子必须在买股票的日子之后),找到最大收益。
注意:收益只能是非负的。
// // main.cpp // leetcode121 // // Created by jzc on 2018/4/30. // Copyright © 2018年 jzc. All rights reserved. // 最大连续子序列变形 // #include <iostream> using namespace std; int main() { int a[10]={1,2}; int sum = a[1]-a[0]; int max = 0; if(sum>max) max = sum; for(int i=1;i<1;i++) { if(sum+a[i+1]-a[i]>(a[i+1]-a[i])) sum=sum+a[i+1]-a[i]; else sum =a[i+1]-a[i] ; if(sum>max) max = sum; } cout<<max<<endl; return 0; }
三.再次进阶连续子序列
基于二,不限制交易次数,进行很多次交易,每次交易只能等上一次交易结束之后,才能开始。收益必须非负。
思路:既然不限次数,那只要将相邻的两个求差,差值如果大于0,就累加起来,最终的累加值就是最大收益
int maxProfit(int* prices, int pricesSize) { int sum = 0; for(int i =1;i<pricesSize;i++) { if(prices[i]>prices[i-1]) sum+=(prices[i]-prices[i-1]); } return sum; }
四. 再次er进阶连续子序列:
leetcode123, 题目大概意思和上面差不多,同样是第i天对应的股票为a[i], 第i天买股票,第j天卖股票,收益为a[j]-a[i](卖股票的日子必须在买股票的日子之后)。找到最大的收益。收益不能为负。
增加了条件:可以进行最多两次交易(两次或一次):比如可以在第一天买股票,第三天卖股票,第五天买股票,第六天卖股票。规定:第二次交易必须要再第一次买卖完之后才可以开始
思路:其实上道题,我的想法还是基于连续子序列的方法。对于这道题我第一的想法是划分:分成第一次和第二次交易,然后最后将两次划分结果求的最大收益加起来就是这道题的解。如果划分成了两段,从第i天划分,第一段是求前i天的最大收益,后一段是求后i天的最大收益。如果我还是按照上题,对每一段求一个最大和连续子序列。。显然复杂度很高。有没有更好的求法,显然是有这样的规律:
对于第i天a[i]要卖掉股票来说,要找一个x,使得a[i]-x是前i天的最大收益,那么我们只要找到最小的x,这个最小的x就是min{a[0].....a[i-1]}。同理如果找后i天的最大收益,就倒着扫描数组,找最大的a[i],是的a[i]-x 最大。
具体代码如下:
int maxProfit(int* prices, int pricesSize) { int *a=(int *)malloc(sizeof(int)*pricesSize); a[0] = 0; int max = 0; int minprices = prices[0]; a[0]=0; for(int i =1;i<pricesSize;i++) { if(prices[i]-minprices>max) max = prices[i]-minprices; a[i] = max; if(prices[i]<minprices) minprices = prices[i]; } int maxprices = prices[pricesSize-1]; max=0; int sum=0; for(int i =pricesSize-2;i>=0;i--) { if(maxprices-prices[i]>max) max = maxprices-prices[i]; if(i>0) { if(max+a[i-1]>sum) sum = max+a[i-1]; } else { if(max>sum) sum = max; } if(prices[i]>maxprices) maxprices = prices[i]; } return sum; }