51.Best Time to Buy and Sell Stock(动态规划)

Say you have an array for which the ith element is the price of a given stock on day i.

If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.

分析:题目要求只能进行一次买卖操作,所以采取动态规划的思想。

sum表示目前已经p[0..i-1]满足条件的最大收益;

low 和 high表示目前已经p[0..i-1]满足条件的买卖价格;

如果新的prices[i]比high大,则将其置为新的high;

prices[i]比low小,则将其置为新的high和low;

拿之前的sum和新生成的high-low的值进行比较,决定是否更新sum的值.

 public int maxProfit(int[] prices) {
		  int len = prices.length;
	        if(len==0){
	            return 0;
	        }
	       int sum = 0;//sum表示目前已经p[0..i-1]满足条件的最大收益
			 
			 int high = prices[0];//low 和 high表示目前已经p[0..i-1]满足条件的买卖价格
			 int low = prices[0];
			 for(int i =1;i<len;i++){
					if(prices[i]>high){//如果新的prices[i]比high大,则将其置为新的high
						high = prices[i];
					}else if(prices[i]<low){//prices[i]比low小,则将其置为新的high和low
						high = prices[i];
						low = prices[i];
					}
					if(sum < high - low){//拿之前的sum和新生成的high-low的值进行比较,决定是否更新sum的值
						sum = high - low;
					}
				}
			 return sum;
	    }

后面做题的时候发现小米2016年校招的题目也用到了这个思想,不同的时候那个题目要求最多可以有两次的买卖操作。

风口之下,猪都能飞。当今中国股市牛市,真可谓“错过等七年”。 给你一个回顾历史的机会,已知一支股票连续n天的价格走势,以长度为n的整数数组表示,数组中第i个元素(prices[i])代表该股票第i天的股价。 假设你一开始没有股票,但有至多两次买入1股而后卖出1股的机会,并且买入前一定要先保证手上没有股票。若两次交易机会都放弃,收益为0。 设计算法,计算你能获得的最大收益。 输入数值范围:2<=n<=100,0<=prices[i]<=100 。

那么题目转化为可以用第i天把所有的n天的股票分开,用left[i]和right[i]表示以第i天分开之后允许买卖一次的最大收益,在左边[0,i]和右边[i+1,len-1]的股票中分别至多买卖一次的收益,即题目转化为用动态规划求在m天内最多只允许买卖一次股票的最大收益。然后比较求得left[i]和right[i]和的最大值。

/**
     * 计算你能获得的最大收益.
     * 已知一支股票连续n天的价格走势,以长度为n的整数数组表示,数组中第i个元素(prices[i])代表该股票第i天的股价。
     * 假设你一开始没有股票,但有至多两次买入1股而后卖出1股的机会,并且买入前一定要先保证手上没有股票。若两次交易机会都放弃,收益为0
     * 
     * @param prices Prices[i]即第i天的股价
     * @return 整型
     */
    public int calculateMax(int[] prices) {
    	int len = prices.length;
    	/*left[i]和right[i]表示以第i天分开,在左边[0,i]和右边[i+1,len-1]的股票中分别至多买卖一次的收益,
    	 * 即题目转化为用动态规划求在m天内最多只允许买卖一次股票的最大收益*/
    	int[] left = new int[len];
    	int[] right = new int[len];
    	int max = 0;//表示整体的最后整体收益
    	for(int i=0;i<len;i++){
    		left[i] = maxProfit(prices,0,i);
    		right[i] = maxProfit(prices,i+1,len-1);
    		if(max <= left[i]+right[i]){
    			max = left[i]+right[i];
    		}
    	}
    	
    	return max;    	
    }
    /**
     * 计算在数组prices的下标[start,end]对应的股票最多允许买卖一次的最大收益.
     * 采用动态规划的思想,同leetcode中51.Best Time to Buy and Sell Stock(动态规划)
     * 
     */
    public int maxProfit(int[] prices,int start,int end) {
		  	int len = end  - start + 1;
		  	
	        if(len<=1){
	            return 0;
	        }
	        
	        int sum = 0;//sum表示目前已经p[0..i-1]满足条件的最大收益
			int high = prices[start];//low 和 high表示目前已经p[0..i-1]满足条件的买卖价格
			int low = prices[start];
			for(int i =start+1;i<=end;i++){
				if(prices[i]>high){//如果新的prices[i]比high大,则将其置为新的high
					high = prices[i];
				}else if(prices[i]<low){//prices[i]比low小,则将其置为新的high和low
					high = prices[i];
					low = prices[i];
				}
				if(sum < high - low){//拿之前的sum和新生成的high-low的值进行比较,决定是否更新sum的值
					sum = high - low;
				}
			}
			return sum;
	    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值