LeetCode 121.买卖股票的最佳时机 动态分配法&暴力法 C语言 Best Time to Buy and Sell Stock

本篇文章为笔者的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!

谢谢你看到这里!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值