1.买卖股票的最好时机(一)
假设你有一个数组prices,长度为n,其中prices[i]是股票在第i天的价格,请根据这个价格数组,返回买卖股票能获得的最大收益
1.你可以买入一次股票和卖出一次股票,并非每天都可以买入或卖出一次,总共只能买入和卖出一次,且买入必须在卖出的前面的某一天
2.如果不能获取到任何利润,请返回0
3.假设买入卖出均无手续费
数据范围: 0≤n≤105,0≤val≤104
要求:空间复杂度O(1),时间复杂度 O(n)
思路解析:
1.只能买卖一次,也就是找到其中的最小的,找到最大的元素
2.假设第一天就是最小的,那就从第二天开始判断,当第二天比min小的时候,min赋值,大的情况,计算利润和第一天比较
非动态规划解法:
public int maxProfit (int[] prices) {
// write code here
//健壮性判断
if(prices==null||prices.length==0) {
return 0;
}
//假设第一天是最小的
int min = prices[0];
int max = 0;
//从第二天开始进行判断
for(int i=1;i<prices.length;i++) {
if(prices[i]<min) {
min = prices[i];
}else{
int temp = prices[i]-min;
if(max<temp) {
max = temp;
}
}
}
return max;
}
动态规划解决:
找到动态规划公式:
即当前得利润和前一天进行比较。
dp[i] = Max(prices[i] - min,dp[i-1]);
public int maxProfit (int[] prices) {
// write code here
//健壮性判断
if(prices==null||prices.length==0) {
return 0;
}
int[] dp = new int[prices.length];
//备忘录
dp[0] = 0;
int min = prices[0];
for(int i=1;i<prices.length;i++) {
min = Math.min(min,prices[i]);
dp[i] = Math.max(prices[i]-min,dp[i-1]);
}
return dp[prices.length-1];
}
2.买卖股票的最好时机(二)
假设你有一个数组prices,长度为n,其中prices[i]是某只股票在第i天的价格,请根据这个价格数组,返回买卖股票能获得的最大收益
1. 你可以多次买卖该只股票,但是再次购买前必须卖出之前的股票
2. 如果不能获取收益,请返回0
3. 假设买入卖出均无手续费
数据范围: 1≤n≤1×105 ,1≤prices[i]≤104
要求:空间复杂度 O(n),时间复杂度O(n)
进阶:空间复杂度O(1),时间复杂度O(n)
思路解析:和题一不同的是可以多次购买股票。
这种情况下,只要某一天比前一天有利润就可以卖了
public int maxProfit (int[] prices) {
// write code here
if(prices==null||prices.length==0) {
return 0;
}
int res = 0;
for(int i=1;i<prices.length;i++) {
if(prices[i]>prices[i-1]){
res+=prices[i]-prices[i-1];
}
}
return res;
}
动态规划:
dp[i] = dp[i-1]+price[i]-price[i-1]
public int maxProfit (int[] prices) {
// write code here
if(prices==null||prices.length==0) {
return 0;
}
int[] dp = new int[prices.length];
dp[0] = 0;
for(int i=1;i<prices.length;i++) {
if(prices[i]>prices[i-1]) {
dp[i] = dp[i-1]+prices[i]-prices[i-1];
}else{
dp[i] = dp[i-1];
}
}
return dp[prices.length-1];
}
3.买卖股票得最好时机(三)
假设你有一个数组prices,长度为n,其中prices[i]是某只股票在第i天的价格,请根据这个价格数组,返回买卖股票能获得的最大收益
1. 你最多可以对该股票有两笔交易操作,一笔交易代表着一次买入与一次卖出,但是再次购买前必须卖出之前的股票
2. 如果不能获取收益,请返回0
3. 假设买入卖出均无手续费
public int maxProfit (int[] prices) {
// write code here
if(prices==null||prices.length==0) {
return 0;
}
//buy1代表第一次买入 sell1代表第一次买入和卖出
int buy1 = -prices[0],sell1 = 0;
//buy2 代表买入2次,卖出一次;sell2代表2次买入卖出
int buy2 = -prices[0],sell2 = 0;
//从第二天开始卖
for(int i=1;i<prices.length;i++) {
if(-prices[i]>buy1) {
buy1 = -prices[i];//第一次买入的最大利润
}
if(buy1+prices[i]>sell1) {
sell1 = buy1+prices[i];//第一次买入卖出的最大利润
}
//第二次买入一次卖出情况下
if(sell1-prices[i]>buy2) {
buy2 = sell1-prices[i];//第二次买入一次卖出情况最大利润
}
//两次情况
if(buy2+prices[i]>sell2) {
sell2 = buy2+prices[i];
}
}
return sell2;
}
x.动态规划总结
动态规划3要素:
1.dp数组
2.dp备忘录
3.dp[i]计算公式

188

被折叠的 条评论
为什么被折叠?



