Best Time to Buy and Sell Stock 最佳时间买入卖出股票(一次买入卖出) @LeetCode

题目:

最佳时间买入卖出股票:你有一个数组保存了股票在第i天的价钱,现在你只能进行一次买入卖出,如何赚的最多

思路:

min记录最小买入价

maxProfit记录最大利润

遍历array,不断更新最小买入价,计算更新最大利润


package Level2;

/**
 * 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.
 */
public class S121 {

	public static void main(String[] args) {

	}
	
	public int maxProfit(int[] prices) {
		// 当没有任何prices信息的情况
		if(prices.length == 0){
			return 0;
		}
        int min = prices[0];		// 记录最小买入价的index
        int maxProfit = 0;			// 记录最大profit
        
        for(int i=1; i<prices.length; i++){
        	// 更新最小买入价
        	if(prices[i] < min){
        		min = prices[i];
        	}
        	
        	// 计算当前利润
        	int currentProfit = prices[i] - min;
        	// 如果当前利润超过最大利润,更新最大利润
        	if(currentProfit > maxProfit){
        		maxProfit = currentProfit;
        	}
        }
        
        return maxProfit;
    }

}


public class Solution {
    public int maxProfit(int[] prices) {
        if(prices.length == 0){
            return 0;
        }
        int minBuy = prices[0];
        int maxProfit = 0;
        
        for(int i=0; i<prices.length; i++){
            minBuy = Math.min(minBuy, prices[i]);
            maxProfit = Math.max(maxProfit, prices[i]-minBuy);
        }
        return maxProfit;
    }
}


采用“局部最优和全局最优解法”:

思路是维护两个变量,一个是到目前为止最好的交易,另一个是在当前一天卖出的最佳交易(也就是局部最优)。递推式是local[i+1]=max(local[i]+prices[i+1]-price[i],0), global[i+1]=max(local[i+1],global[i])。这样一次扫描就可以得到结果,时间复杂度是O(n)。而空间只需要两个变量,即O(1)。

http://blog.csdn.net/linhuanmars/article/details/23162793

有两点值得注意:

1 在第i天买入,在i+1天卖出,再在i+1天买入,在i+2天卖出,等效于在i天买入在i+2天卖出:p[i+2]-p[i] = -p[i]+p[i+1]-p[i+1]+p[i+2]

2 如果计算出没两天的差值:diff1, diff2, diff3 则此题就转化为maximum subarray的问题

public class Solution {
    public int maxProfit(int[] prices) {
        int len = prices.length;
        if(len == 0){
            return 0;
        }
        int[] local = new int[len+1];
        int[] global = new int[len+1];
        
        local[0] = 0;
        global[0] = 0;
        for(int i=1; i<len; i++) {
            int diff = prices[i] - prices[i-1];
            local[i] = Math.max(local[i-1]+diff, Math.max(diff, 0));
            global[i] = Math.max(global[i-1], local[i]);
        }
        
        return global[len-1];
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值