力扣 121. 买卖股票的最佳时机 C语言实现

题目描述:

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

题目来源

官方暴力解法不可用!!会超出时间控制

方法:使用动态规划

已知 i 个元素为股票 i 天的价格

大问题:所有天数的最大利润。

子问题:前 i 个天数的最大利润。

示例:[7,1,5,3,6,4]

初始化股票的最小价格minprice=prices[0]=7,设前 i 天最大利润为dp[i]

前一天最大利润:很显然dp[0] = 0,比较当前值与最小价格,将小的值赋给minprice。由于初始化时已经将第一天的价格赋给了最小价格,第一天可以不用比较。

前二天最大利润:dp[1] = max[前一天的最大利润, 当前价格 - 最小价格] = max[0, 1-7]=0,找最小价格,minprice=min[当前价格, minprice] = [1, 7]=1

前三天最大利润:dp[2] = max[dp[1], prices[2]-minprice]=max[0, 5-1]=4

.............

即状态方程为:

dp[i] = max\left \{ dp[i-1], prices[i]-minprice \right \}

依次执行到数组末尾,然后遍历dp数组,找到最大的值即为所有天数的最大利润。

int maxProfit(int* prices, int pricesSize){
    int dp[pricesSize];
    dp[0] = 0;
    int minprice = prices[0];
    int maxp=0;
    for(int i=1; i<pricesSize; ++i)
    {
        //获取前i天最大利润
        dp[i] = dp[i-1]>(prices[i]-minprice)?dp[i-1]: prices[i]-minprice;
        //更新最小价格
        minprice = minprice<prices[i]?minprice:prices[i];
    }
    //寻找最大利润
    for(int i=0; i<pricesSize; ++i)
    {
        maxp = maxp>dp[i]?maxp:dp[i];
    }
    return maxp;
}

动态规划优化

与之前写最大子数组和的时候一样,由于动态规划的方程只与前一个子问题有关,用变量代替dp[i]是最优方案。从上面已经推出来状态方程为:

dp[i] = max\left \{ dp[i-1], prices[i]-minprice \right \}

而最终问题 maxp = max{ dp[i] }

设置变量pre代替dp[i-1],并定义一个变量nowmax记录最大的dp[i]即可替代dp数组

修改后的代码如下:

int maxProfit(int* prices, int pricesSize){
    int pre = 0;
    int minprice = prices[0];
    int maxp=0;
    int nowmax=0;
    for(int i=1; i<pricesSize; ++i)
    {
        //获取前i天最大利润
        nowmax = pre>(prices[i]-minprice) ? pre: prices[i]-minprice;
        //判断前i天最大利润是否大于当前最大利润
        maxp = maxp>nowmax ? maxp:nowmax;
        //更新最小价格
        minprice = minprice<prices[i] ? minprice:prices[i];
        //获取当前最大利润进行下一轮循环比较
        pre = nowmax;
    }
    return maxp;
}

然而经过观察发现,前 i-1 天的最大利润 pre 根本不需要定义,因为在下一次循环时当前 nowmax记录的即为前 i-1 天的最大利润,直接进行比较即可。代码修改如下:

int maxProfit(int* prices, int pricesSize){
    int minprice = prices[0];
    int maxp=0;
    int nowmax=0;
    for(int i=1; i<pricesSize; ++i)
    {
        //获取前i天最大利润
        nowmax = nowmax>(prices[i]-minprice)?nowmax: prices[i]-minprice;
        //判断前i天最大利润是否大于当前最大利润
        maxp = maxp>nowmax ? maxp:nowmax;
        //更新最小价格
        minprice = minprice<prices[i] ? minprice:prices[i];
    }
    return maxp;
}

写的有点啰嗦,只为记录当前的解题思路。欢迎交流~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值