代码改变世界

[LeetCode] 121. Best Time to Buy and Sell Stock_Easy tag: Dynamic Programming

2018-08-03 23:27  Johnson_强生仔仔  阅读(213)  评论(0编辑  收藏  举报

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 (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit.

Note that you cannot sell a stock before you buy one.

Example 1:

Input: [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
             Not 7-1 = 6, as selling price needs to be larger than buying price.

Example 2:

Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.

05/08/2019 update: 其实这个题目就是[LeetCode] 53. Maximum Subarray_Easy tag: Dynamic Programming的马甲题。将每个nums[i] = nums[i] - nums[i - 1], i > 1, 就是求maximum subarray。
Code
class Solution:
    def bestBuySell(self, nums):
        if not nums: return 0
        n = len(nums)
        arr, ans = [0]*n, 0
        for i in range(1, n):
            arr[i] = nums[i] - nums[i - 1]
        mem = [0] * n
        for i in range(1, n):
            mem[i] = max(mem[i - 1] + arr[i], arr[i])
            ans = max(ans, mem[i])
        return ans

 


题目思路为DP, 用两个dp数组来实现, min_dp[i] 是指到i index为止的最小值, dp[i] 表示到 i index 为止能得到的最大收益
动态方程式为 min_dp[i] = min(min_dp[i-1], a[i]) , dp[i] = max(dp[i-1], a[i] - min_dp[i]), 利用滚动数组, 实现S: O(1)
init: dp[0] = 0, min_dp[0] = a[0]

1. Constraints
1) edge case: [] => 0

2. Ideas

DP T: O(n) S; O(1) using rolling array

3. Code
class Solution:
    def buySellStock(self, prices):
        if not prices: return 0
        n = len(prices)
        min_dp, dp = [0]*2, [0]*2
        min_dp[0], ans = prices[0], 0
        for i in range(1, n):
            min_dp[i%2] = min(min_dp[i%2-1], prices[i])
            dp[i%2] = max(dp[i%2-1], prices[i] - min_dp[i%2])
            ans = max(ans, dp[i%2])
        return ans