买卖股票相关问题:
1,只能买卖一次:
假设有一个数组,它的第i个元素是一支给定的股票在第i天的价格。
如果你最多只允许完成一次交易,设计一个算法来找出最大利润。
例如:[3,4,5,1,9]
输出:8
解释:第四天买入,第五天卖出
原理:为了减少复杂度,这里用峰谷的方法遍历
在第一个不亏损的日子买入,然后比较,如果后一天不卖是亏损还是接着赚。
亏损就放弃这一段,从下一个日子开始继续分析
接着赚就不放弃。
【说实话我觉着难点在怎么记这个开始和结束的日子,我还试了一下,挺麻烦的】
c++实现代码如下:
int main()
{
int array[5] = {1,2,5,4,3};
int max = 0;
int num =0;
for (int i = 0; i < sizeof(array)/sizeof(array[0]) - 1; i++)
{
num = num + (array[i + 1] - array[i]);
if (num < 0)
{
num = 0;
continue;
}
if (max < num)
{
max = num;
}
}
if (max == 0)
{
printf("别买了吧就\n");
}
else
{
printf("能赚%d块钱",max);
}
}
2,可以无限次买卖
【其实这个在第三个,但我觉着它比第三个简单点……甚至比第一个简单】
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易
例;
输入:【1,2,3,5,2】
输入:4
原理非常简单:比较相邻两次的值,能赚就买,会亏就不买
代码如下:
int main()
{
int array[5] = {1,2,5,4,3};
int max = 0;
int num =0;
for (int i = 0; i < sizeof(array)/sizeof(array[0]) - 1; i++)
{
if (array[i + 1] > array[i])
{
max += array[i + 1] - array[i];
}
}
if (max == 0)
{
printf("别买了吧就\n");
}
else
{
printf("能赚%d块钱",max);
}
}
3,只限两次买卖:
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 1:
输入: [3,3,5,0,0,3,1,4]
输出: 6
解释: 在第 4 天(股票价格 = 0)的时候买入,在第 6 天(股票价格 = 3)的时候卖出,这笔交易所能获得利润 = 3-0 = 3 。
随后,在第 7 天(股票价格 = 1)的时候买入,在第 8 天 (股票价格 = 4)的时候卖出,这笔交易所能获得利润 = 4-1 = 3 。
这部分借鉴的这篇文章:https://blog.csdn.net/lzz_zz/article/details/102860884
看这段的时候满脑子,妈妈这段代码好牛逼……
嗯……把大佬的思路展开一下!
【为了做这题我还去捡了一下动态规划】
简单的说,其实可以把两次买卖规划成这样:
第一天:买/卖/维持
第二天:买/卖/维持
……
每个结点有自己的值(股票价格)
其实就是一个四层的树
不过也有特别的地方,比如如果第一天没买,第二天就不可能卖,不过这点我们后说。
把每个结点动态规划出来:
【前面是不操作,后面是操作】
s1[i] = max(s1[i-1],-price)
s2[i] = max(s2[i-1],s1[i-1]+price)
s3[i] = max(s3[i-1],s2[i-1]-price)
s4[i] = max(s4[i-1],s3[i-1]+price)
动态规划是一种自底向上的结构——但是这里的循环排序是s4,s3,s2,s1这样的,为什么呢?
因为,开始时设定的s1为负无穷,s3为负无穷,这样在位置为1的时候前三者都处于极限状态,只有s1能够获得实际数值——而s1能影响下个位置的s2,事实上,这还是从s1往上讨论的。
而s2的判断方式和第一问,一次买卖的想法类似。
实现代码如下:
#include <iostream>
#include <stdlib.h>
int max(int a, int b)
{
if (a > b)
return a;
else
return b;
}
int main()
{
int array[6] = {3,2,5,4,3,6};
int s1 = INT8_MIN, s2 = 0, s3 = INT8_MIN, s4 = 0;
for (int i = 0; i < sizeof(array) / sizeof(array[0]); i++)
{
s4 = max(s4,s3+array[i]);
s3 = max(s3, s2 - array[i]);
s2 = max(s2, s1 + array[i]);
s1 = max(s1, -array[i]);
}
printf("%d",s4);
return 0;
}