买卖股票的最佳时机 II
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 1:
输入: [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
示例 2:
输入: [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
示例 3:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
在做这道题时,提取条件:只有当前未买入且当天价格小于第二天时才能买入;只有已经买入,当前价格大于买入价格且当前价格大于第二天时才能卖出。为了避免在之前的判断出现数组下标越界的情况,需要单独考虑倒数第一天和倒数第二天的情况。
C#代码如下:执行用时:120 ms,内存消耗 :24.2 MB。
public class Solution {
public int MaxProfit(int[] prices) {
int inPrice = 0; //买入的价格
int outPrice = 0;//卖出的价格
int profit = 0;//收益
bool flag = false;//是否已买入
int len = prices.Length;
for (int i = 0; i < len; i++)
{
//当未买入且i不为最后一天且当前价格比第二天低时,买入
if (!flag && i!=len-1 && prices[i]<prices[i+1])
{
inPrice = prices[i];
flag = true;
continue;
}
//当已买入且当前价格高于收入价格时
if (flag && prices[i]>inPrice)
{
if (i == len - 1) //最后一天时
{
outPrice = prices[i];
profit += (outPrice - inPrice); //收益累计
//完成一轮交易,重置
flag = false;
inPrice = 0;
outPrice = 0;
}
else if (prices[i] > prices[i + 1]) //不是最后一天且当前价格高于第二天价格时才卖出(避免数组下标越界)
{
outPrice = prices[i];
profit += (outPrice - inPrice); //收益累计
//完成一轮交易,重置
flag = false;
inPrice = 0;
outPrice = 0;
}
}
}
return profit;
}
}
Java代码如下,执行用时:2 ms,内存消耗 :37.6 MB。
class Solution {
public int maxProfit(int[] prices) {
int inPrice = 0; //买入的价格
int outPrice = 0;//卖出的价格
int profit = 0;//收益
Boolean flag = false;//是否已买入
int len = prices.length;
for (int i = 0; i < len; i++)
{
//当未买入且i不为最后一天且当前价格比第二天低时,买入
if (!flag && i != len - 1 && prices[i] < prices[i + 1])
{
inPrice = prices[i];
flag = true;
continue;
}
//当已买入且当前价格高于收入价格才卖出
if (flag && prices[i] > inPrice)
{
if (i == len - 1) //最后一天且当前价格高于收入价格时
{
outPrice = prices[i];
profit += (outPrice - inPrice); //收益累计
//完成一轮交易,重置
flag = false;
inPrice = 0;
outPrice = 0;
}
else if (prices[i] > prices[i + 1]) //不是最后一天且当前价格高于第二天价格时才卖出(避免数组下标越界)
{
outPrice = prices[i];
profit += (outPrice - inPrice); //收益累计
//完成一轮交易,重置
flag = false;
inPrice = 0;
outPrice = 0;
}
}
}
return profit;
}
}
优化
计算时不用管实际操作是怎么样,本质上来说只要每一次收益都能够获得就是最大收益。
优化后C#代码如下,执行用时 :116 ms,内存消耗 :24.3 MB。
public class Solution {
public int MaxProfit(int[] prices) {
int profit = 0;//收益
for (int i = 1; i < prices.Length; i++)
{
if (prices[i] > prices[i - 1])
{
profit += (prices[i] - prices[i - 1]);
}
}
return profit;
}
}
优化后java代码如下,执行用时 :1 ms,内存消耗 :37.5 MB。
class Solution {
public int maxProfit(int[] prices) {
int profit = 0;//收益
for (int i = 1; i < prices.length; i++)
{
if (prices[i] > prices[i - 1])
{
profit += (prices[i] - prices[i - 1]);
}
}
return profit;
}
}