题目描述:
给定一个数组,它的第 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。
来源:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/
代码实现:
1 def maxProfit(prices): 2 ''' 3 买卖股票的最佳时机,返回最大利润-暴力解法 4 5 :param prices: 6 :return: 7 ''' 8 if len(prices) == 0: 9 return 0 10 right = 0 11 max_pro = [] # 存储每次买入情况下的最大利润 12 while right < len(prices): 13 cur = prices[right] # 表示买入价格 14 maxAns = 0 # 表示当前买入情况下的最大利润 15 for i in range(right, len(prices)): 16 maxAns = max(prices[i] - cur, maxAns) 17 max_pro.append(maxAns) 18 right += 1 19 20 print("max_pro=", max_pro) 21 22 return max(max_pro) 23 24 25 print("----------测试maxProfit(prices)-----------") 26 prices = [] 27 res = maxProfit(prices) 28 print("res=", res) 29 30 31 def maxProfit1(prices): 32 ''' 33 买卖股票的最佳时机,返回最大利润-暴力解法 34 :param prices: 35 :return: 36 ''' 37 if len(prices) == 0: 38 return 0 39 right = 0 40 maxPro = 0 # 表示最大利润 41 while right < len(prices): 42 cur = prices[right] # 表示买入价格 43 maxAns = 0 # 表示当前买入情况下的最大利润 44 for i in range(right, len(prices)): 45 maxAns = max(prices[i] - cur, maxAns) 46 maxPro = max(maxPro, maxAns) 47 right += 1 48 49 return maxPro 50 51 52 print("----------测试maxProfit(prices)-----------") 53 prices = [2, 4, 1, 4, 5, 6, 7, 2, 9, 2] 54 res = maxProfit1(prices) 55 print("res=", res) 56 57 58 def maxProfit2(prices): 59 ''' 60 买卖股票的最佳时机,返回最大利润--暴力法: 61 :param prices: 62 :return: 63 ''' 64 ans = 0 65 for i in range(len(prices)): 66 for j in range(i + 1, len(prices)): 67 ans = max(ans, prices[j] - prices[i]) 68 return ans 69 70 71 print("----------测试maxProfit(prices)-----------") 72 prices = [2, 4, 1, 4, 5, 6, 7, 2, 9, 2] 73 res = maxProfit2(prices) 74 print("res=", res) 75 76 77 def maxProfit3(prices): 78 ''' 79 买卖股票的最佳时机,返回最大利润-: 80 :param prices: 81 :return: 82 ''' 83 minprice = float("inf") # 表示正无穷 84 maxprofit = 0 85 for price in prices: 86 maxprofit = max(price - minprice, maxprofit) 87 minprice = min(price, minprice) 88 return maxprofit 89 90 91 print("----------测试maxProfit(prices)-----------") 92 prices = [2, 4, 1, 4, 5, 6] 93 res = maxProfit3(prices) 94 print("res=", res)
输出:
----------测试maxProfit(prices)----------- res= 0 ----------测试maxProfit(prices)----------- res= 8 ----------测试maxProfit(prices)----------- res= 8 ----------测试maxProfit(prices)----------- res= 5
总结:上述代码一共有四种编码方式,从思想角度来说,前三种思想相同,都是暴力解法求解最大利润。
暴力解法:计算每次买入情况下得最大利润,然后输出利润最大值即可。可以采用两层for循环遍历实现。或者结合while和for循环实现。方法1和2稍有不同,主要体现在方法1设置了额外列表用来存储每次买入情况下得最大利润,最后返回列表最大值即可。方法2设置变量代表最大利润,每次求得利润后,与当前最大利润比较迭代即可。
方法4是官方解法,官方解释:
我们来假设自己来购买股票。随着时间的推移,每天我们都可以选择出售股票与否。那么,假设在第 i 天,如果我们要在今天卖股票,那么我们能赚多少钱呢?
显然,如果我们真的在买卖股票,我们肯定会想:如果我是在历史最低点买的股票就好了!太好了,在题目中,我们只要用一个变量记录一个历史最低价格 minprice,我们就可以假设自己的股票是在那天买的。那么我们在第 i 天卖出股票能得到的利润就是 prices[i] - minprice。
因此,我们只需要遍历价格数组一遍,记录历史最低点,然后在每一天考虑这么一个问题:如果我是在历史最低点买进的,那么我今天卖出能赚多少钱?当考虑完所有天数之时,我们就得到了最好的答案。
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/solution/121-mai-mai-gu-piao-de-zui-jia-shi-ji-by-leetcode-/
来源:力扣(LeetCode)