26 递归、动态规划双指针求解买卖股票的最佳时机

问题描述:给定一个数组,他的第i个元素是一只给定股票第i天的价格,如果你最多只允许完成一笔交易(即买入和卖出一只股票一次),设计一个算法计算你所能获取的最大利润,你不能在买入股票前卖出股票。

递归求解思路:用一个参数变量记录手里是否有股票,若有可以选择卖,然后立即返回(因为只允许有一次交易),也可以选择不卖继续往下走。如果没有可以选择继续向下走,或者买一张股票;



 

public getMaxProfit(int []prices,int index,int isHave,int times)
{
if(index==prices.length-1)
{
if (isHave)
{
return prices[prices.length-1];
}else
{
return 0;
}
}

if(times==1)
{
return 0;
}
if(isHave)
{
return Math.max(getMaxProfit(prices,index+1,false,1)+prices[index],getMaxProfit(prices,index+1,isHave,0));
}else
{
return Math.max(getMaxProfit(prices,index+1,false,0),getMaxProfit(prices,index+1,true,0)-prices[index]);
}
}

public GetMaxProfit(int [] prices)
{
return getMaxProfit(prices,0,0,0);
}

动态规划求解;定义dp[i][0][0]为在第i天手上没有股票且没卖过股票的最大利润,dp[i][0][1]表示第i天手上没有股票,但是卖过一次的最大利润,dp[i][1][0]表示第i天持有股票的最大利润,dp[i][1][1]不存在。

public getMaxProfit(int[]prices)
{
int [][][]dp=new int[prices.length][2][2];
dp[0][0][0]=0;
dp[0][1][0]=-prices[0];
dp[0][0][1]=0;
for(int i=1;i<prices.length;i++)
{
dp[i][0][0]=dp[][i-1][0][0];
dp[i][1][0]=Math.max(dp[i-1][1][0],dp[i-1][0][0]-prices[i]);
dp[i][0][1]=Math.max(dp[i-1][0][1],dp[i-1][1][0]+prices[i]);
}
return Math.max(dp[prices.length][0][1],0);
}

最大差值上升子序列:可以利用双指针求得所有的上升子序列,并存在PriorityQueue(最大堆中)最后弹出最大堆。

public getMaxProfit(int []prices)
{
int slowIndex=0;
int fastIndex=1;
int sum=0;
PriorityQueue<Integer>maxHeap=new PriorityQueque<>(Collections.reverseOrder());
while(fastIndex<prices.length)
{
if(prices[fastIndex]>=prices[fastIndex-1])
{
fastIndex++;
}else
{
sum=prices[fastIndex-1]-prices[slowIndex];
maxHeap.add(sum);
sum=0;
slowIndex=fastIndex;
fastIndex+=1;
}
}
if(fastIndex-1==prices.length-1)
{
maxheap.add(prices[prices.length-1]-prices[slowIndex]);
}
return maxheap.poll();
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值