Best Time to Buy and Sell Stock III :from LeetCode

题目大意是:给一个股票价格数组,你最多能买卖两次,问最大收益

比如输入 2 4 则最大收益是2

输入 1 20 2 30 则最大收益是19+28

之前网上有一段DP的代码时间复杂度是o(n)这是满足时间要求的,但空间复杂度是o(n),其实DP都是用空间换时间的方法。有兴趣可以上网搜一搜,自己写也不麻烦

现在和大家说说时间复杂度为o(n),空间复杂度为o(1)的一个办法。


大家还记得求买卖一次的最大收益的方法吧?

我们先求该数组中买卖一次的最大收益max0. 并且记下买和卖时的数组下标或迭代器指针。就当买时的下标为a卖时为b

然后我们求下标0到a-1的子数组中买卖一次的最大收益max1

和下标b+1到end()的子数组中买卖一次的最大收益max2

以及a+1到b-1的子数字中买卖一次的最大亏损(得为负数)取正后为max3

最后我们要的结果就是max0 + max(max1,max2,max3)

呵呵方法其实很简单,这里就不提供数学证明了,如果有疑问可以讨论,如下给我我在leetcode上的C++代码实现,程序写的拙劣,希望大家给出批评指导意见,无论是对算法的改进,还是从程序设计或软件工程角度的想法意见。希望大家不吝赐教!!

class Solution {
public:
    vector<int>::iterator right,left;
    int find(vector<int> &prices,vector<int>::iterator lef,vector<int>::iterator rig)
    {
        int min=1000000000,maxs=0;
        vector<int>::iterator lefbuf;
        while(lef<rig)
        {
            if(*lef<min)
            {
                min=*lef;
                lefbuf=lef;
            };
            if(*lef>min && (*lef-min)>maxs)
            {
                maxs=*lef-min;
                left=lefbuf;
                right=lef;
            };
            lef++;
        };
        return maxs;
    };
    
    int rfind(vector<int> &prices,vector<int>::iterator lef,vector<int>::iterator rig)
    {
        int min=1000000000,maxs=0;
        while(lef<rig)
        {
            if(*rig<min)
            {
                min=*rig;
            };
            if(*rig>min && (*rig-min)>maxs)
            {
                maxs=*rig-min;
            };
            rig--;
        };
        return maxs;
    }
    int maxProfit(vector<int> &prices) {
        int max,max1,max2,max3;
        vector<int>::iterator bufright,bufleft;
        max1=max2=max3=0;
        max=find(prices,prices.begin(),prices.end());
        if(max==0)return 0;
        bufright=right;bufleft=left;
        max1=find(prices,prices.begin(),bufleft);
        max2=rfind(prices,bufleft,bufright-1);
        max3=find(prices,bufright+1,prices.end());
        if(max1>max2)max2=max1;
        if(max2>max3)max3=max2;
        return max+max3;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值