0
点赞
收藏
分享

微信扫一扫

[动态规划]BM81 买卖股票的最好时机(二)-中等

​​BM81 买卖股票的最好时机(二)​​

知识点​​贪心​​​​动态规划​​

描述

假设你有一个数组prices,长度为n,其中prices[i]是某只股票在第i天的价格,请根据这个价格数组,返回买卖股票能获得的最大收益1. 你可以多次买卖该只股票,但是再次购买前必须卖出之前的股票2. 如果不能获取收益,请返回03. 假设买入卖出均无手续费

数据范围: [动态规划]BM81 买卖股票的最好时机(二)-中等_贪心算法 , [动态规划]BM81 买卖股票的最好时机(二)-中等_贪心算法_02要求:空间复杂度 [动态规划]BM81 买卖股票的最好时机(二)-中等_动态规划_03,时间复杂度 [动态规划]BM81 买卖股票的最好时机(二)-中等_动态规划_03

进阶:空间复杂度 [动态规划]BM81 买卖股票的最好时机(二)-中等_数组_05,时间复杂度 [动态规划]BM81 买卖股票的最好时机(二)-中等_动态规划_03

示例1

输入:

[8,9,2,5,4,7,1]

复制返回值:

7

复制说明:

在第1天(股票价格=8)买入,第2天(股票价格=9)卖出,获利9-8=1
在第3天(股票价格=2)买入,第4天(股票价格=5)卖出,获利5-2=3
在第5天(股票价格=4)买入,第6天(股票价格=7)卖出,获利7-4=3
总获利1+3+3=7,返回7

示例2

输入:

[5,4,3,2,1]

复制返回值:

0

复制说明:

由于每天股票都在跌,因此不进行任何交易最优。最大收益为0。

示例3

输入:

[1,2,3,4,5]

复制返回值:

4

复制说明:

第一天买进,最后一天卖出最优。中间的当天买进当天卖出不影响最终结果。最大收益为4。

题解

贪心解法

对于一个数组的任意一个片段,一定存在这样的三个序列中的至少一个:

  1. 平滑序列:连续的元素值都相等
  2. 上升序列:a[i] > a[i-1]
  3. 下降序列:a[i]<a[i-1]

对于股票的买卖时机,实际上就是找出这个数组中所有的上升序列,并求这些序列差值之和。假如有一个长度为n的上升序列a,那么a[n-1] - a[0]就是我们要的利润差值。按照这个思路,我们需要找出题目给定数组中所有上升序列的起始位置和结束位置。但是如果我们将上面的公式变换一下,就不需要进行记录了:

profit = a[n-1] - a[0] = (a[n-1]-a[n-2]) + (a[n-2] - a[0]) =  (a[n-1] - a[n-2]) + (a[n-2] -a[n-2])+...+(a[1]-a[0])

根据上面的等式可知,上升序列两段的差值,实际上等于上升序列中所有相邻2个元素差值之和。因此可以很容易的写出代码,如下:

#include <bits/stdc++.h>

using namespace std;
int maxProfit(vector<int> &prices)
{
if (prices.size() <= 1)
{
return 0;
}

int max_profit = 0;
for (int i = 1; i < prices.size(); ++i)
{
if (prices[i] > prices[i - 1])
{
max_profit += (prices[i] - prices[i - 1]);
}
}
return max_profit;
}


动态规划解法


int maxProfit_dp(vector<int> &prices)
{
if (prices.empty())
{
return 0;
}
// dp[i]表示当前的最大利润
std::vector<int> dp(prices.size(), 0);
for (int i = 1; i < prices.size(); ++i)
{
if (prices[i] < prices[i - 1])
{
dp[i] = dp[i - 1];
}
else
{
dp[i] = dp[i - 1] + prices[i] - prices[i - 1];
}
}
return dp.back();
}
举报

相关推荐

0 条评论