leetcode刷题121 买卖股票的最佳时机 Best Time to Buy and Sell Stock(简单) Python Java

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。

注意你不能在买入股票前卖出股票。

示例 1:

输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
         注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。


示例 2:

输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

扫描价格数组,维护一个最小值,当前元素-最小值>最大利润时,更新最大利润即可。

class Solution(object):
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        if not prices: # 列表为空是False
            return 0
        buy=prices[0] # 初始化第一个元素为最小元素
        out=0
        for i in range(1,len(prices)):
            if prices[i]<buy:
                buy=prices[i]
            else:
                out=max(out,prices[i]-buy)  
        return out

if __name__ == '__main__':
    a = Solution()
    result = a.maxProfit([7,1,5,3,6,4])
    print(result)

结果为5,与题目一致

 

以下是Java版本:

题目大意:给一个数组prices[]prices[i]代表股票在第i天的售价,求出只做一次交易(一次买入和卖出)能得到的最大收益。 

解题思路:只需要找出最大的差值即可,即 max(prices[j] – prices[i]) i < j。一次遍历即可,在遍历的时间用遍历low记录 prices[o….i] 中的最小值,就是当前为止的最低售价,时间复杂度为 O(n)

public class Solution {
    public int maxProfit(int[] prices) {

        if (prices == null || prices.length < 1) {
            return 0;
        }

        int min = prices[0];
        int profit = 0;

        // 第i天的价格可以看作是买入价也可以看作是卖出价
        for (int i = 1; i < prices.length; i++) {
            // 找到更低的买入价
            if (min > prices[i]) {
                // 更新买入价
                min = prices[i];
            } 
            // 当天的价格不低于买入价
            else {
                // 如果当天买出的价格比之前卖出的价格高
                if (profit < prices[i] - min) {
                    // 更新卖出价
                    profit = prices[i] - min;
                } 
            }
        }
        return profit;
    }
}

这道题求进行一次交易能得到的最大利润。如果用brute force的解法就是对每组交易都看一下利润,取其中最大的,总用有n*(n-1)/2个可能交易,所以复杂度是O(n^2)
很容易感觉出来这是动态规划的题目,其实跟Maximum Subarray非常类似,用局部最优和全局最优解法。思路是维护两个变量,一个是到目前为止最好的交易,另一个是在当前一天卖出的最佳交易(也就是局部最优)。递推式是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)。代码如下:

1.	public int maxProfit(int[] prices) {  
2.	    if(prices==null || prices.length==0)  
3.	        return 0;  
4.	    int local = 0;  
5.	    int global = 0;  
6.	    for(int i=0;i<prices.length-1;i++)  
7.	    {  
8.	        local = Math.max(local+prices[i+1]-prices[i],0);  
9.	        global = Math.max(local, global);  
10.	    }  
11.	    return global;  
12.	}  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值