本篇文章为笔者的LeetCode刷题笔记。文章整体分为两部分:1.笔者自己思考的算法及代码。2.LeetCode官方给出的最优算法及代码。通过对比这两部分算法和代码的异同,笔者的算法思想和编程水平有了显著地提升。如果这篇文章能帮到你那真是再好不过了!
一、读者思考的算法
A.算法:从后向前依次做减法,找出最大值。循环pricesSize-1次,因为数组第一个元素不必再相减。
int maxProfit(int* prices, int pricesSize){
int curprofit=0; int maxprofit=0;
int fortimes=pricesSize;
for(int i=1;i<pricesSize;i++){
for(int j=1;j<fortimes;j++){
if(prices[pricesSize-i]-prices[pricesSize-i-j]>0){
curprofit=prices[pricesSize-i]-prices[pricesSize-i-j];
maxprofit=fmax(maxprofit,curprofit);
}
}
fortimes--;
}
return maxprofit;
}
//第二种写法 简洁了一下代码 从前往后i+1 - i
int maxProfit(int* prices, int pricesSize){
int curprofit=0; int maxprofit=0;
for(int i=0;i<pricesSize;i++){
for(int j=i+1;j<pricesSize;j++){
if(prices[j]-prices[i]>0){
curprofit=prices[j]-prices[i];
}
maxprofit= fmax(curprofit,maxprofit);
}
}
if(maxprofit){
return maxprofit;
}
return 0;
}
然而,时间复杂度太高,超出了时间限制。
二、官方算法
A.算法:从第二天开始,每天都做这件事:curmaxprofit=当日股价-历史最低股价;与全局最大利润maxprofit做比较,若curmaxprofit>maxprofit,则curmaxprofit=maxprofit;同时不断将当日股价与历史最低股价对比并更新,原理同上。
int maxProfit(int* prices, int pricesSize){
int min=prices[0];int maxprofit=0;int curmaxprofit=0;
for(int i=1;i<pricesSize;i++){ //一次遍历数组
curmaxprofit=prices[i]-min; //第i天股价-至今为止历史最低股价 = 至今最大利润
maxprofit=fmax(maxprofit,curmaxprofit); //至今最大利润与全局最大利润比较,有可能后面的利润会比至今最大利润高
min=fmin(min,prices[i]); //第i天股价与历史最低股价取最小,即遍历数组的过程中不断更新min的值
}
if(maxprofit>0){
return maxprofit; //若出现诸如[7,4,3,1]这种情况,按题目要求,返回0
}else{
return 0;
}
}
- 时间复杂度:O(n),只需要遍历一次。
- 空间复杂度:O(1),只使用了常数个变量。
三、笔者小结
从O(n^2)暴力解到O(n)一次遍历代码简单,时间复杂度也低了很多。
其实一次遍历的思想就是动态规划与Leetcode 53.最大子序和是一个思路,都用到了动态分配。
https://mp.csdn.net/mp_blog/creation/editor/118670328
Keep calm and carry on!
谢谢你看到这里!