#  121. Best Time to Buy and Sell Stock
**<font color=red>难度: Easy</font>**

## 刷题内容

> 原题连接

* https://leetcode.com/problems/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 (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.
```

## 解题方案


> 思路 1
******- 时间复杂度: O(N)******- 空间复杂度: O(N)******



对于从第一天后的每一天i来说：
- 如果我们在第i天卖出，则能赚的钱是在第i-1卖能赚到的钱+（第i天的股价 - 第i-1的股价）
- 如果我们在第i天不卖出，则当前赚的钱为 0 

所以对于第一天后的第i天来说，他能赚到的最多的钱就是上面两种情况中的较大值


All the straight forward solution should work, but if the interviewer twists the question slightly 
by giving the difference array of prices, Ex: for ```{1, 7, 4, 11}```, if he gives ```{0, 6, -3, 7}```, 
you might end up being confused.

Here, the logic is to calculate the difference ```(maxCur += prices[i] - prices[i-1])```
of the original array, and find a contiguous subarray giving maximum profit. 
If the difference falls below ```0```, reset it to zero.

参考[Maximum subarray problem](https://en.wikipedia.org/wiki/Maximum_subarray_problem), 
[Kadane's Algorithm](https://discuss.leetcode.com/topic/19853/kadane-s-algorithm-since-no-one-has-mentioned-about-this-so-far-in-case-if-interviewer-twists-the-input)


```
Why maxCur = Math.max(0, maxCur += prices[i] - prices[i-1]); ?

Well, we can assume opt(i) as the max Profit you will get if you sell the stock at day i;

We now face two situations:

We hold a stock at day i, which means opt(i) = opt(i - 1) - prices[i - 1] + prices[i] (max Profit you can get if you sell stock at day(i-1) - money you lose if you buy the stock at day (i-1) + money you gain if you sell the stock at day i.

We do not hold a stock at day i, which means we cannot sell any stock at day i. In this case, money we can get at day i is 0;

opt(i) is the best case of 1 and 2.

So, opt(i) = Max{opt(i - 1) - prices[i - 1] + prices[i], 0}
```


```python
class Solution(object):
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        if not prices or len(prices) == 0:
            return 0
        opt = [0] * len(prices)
        for i in range(1, len(prices)):
            opt[i] = max(opt[i-1]+prices[i]-prices[i-1], 0)
        return max(opt)
```

> 思路 2
******- 时间复杂度: O(N)******- 空间复杂度: O(1)******


```python
class Solution(object):
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        if not prices or len(prices) == 0:
            return 0
        res, max_cur = 0, 0
        for i in range(1, len(prices)):
            max_cur = max(0, max_cur+prices[i]-prices[i-1]) 
            res = max(res, max_cur)
        return res
```



