#
# @lc app=leetcode id=121 lang=python3
#
# [121] Best Time to Buy and Sell Stock
#
# https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/
#
# algorithms
# Easy (52.31%)
# Likes:    9753
# Dislikes: 399
# Total Accepted:    1.4M
# Total Submissions: 2.8M
# Testcase Example:  '[7,1,5,3,6,4]'
#
# You are given an array prices where prices[i] is the price of a given stock
# on the i^th day.
#
# You want to maximize your profit by choosing a single day to buy one stock
# and choosing a different day in the future to sell that stock.
#
# Return the maximum profit you can achieve from this transaction. If you
# cannot achieve any profit, return 0.
#
#
# Example 1:
#
#
# Input: prices = [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.
# Note that buying on day 2 and selling on day 1 is not allowed because you
# must buy before you sell.
#
#
# Example 2:
#
#
# Input: prices = [7,6,4,3,1]
# Output: 0
# Explanation: In this case, no transactions are done and the max profit =
# 0.
#
#
#
# Constraints:
#
#
# 1 <= prices.length <= 10^5
# 0 <= prices[i] <= 10^4
#
#
#
import unittest
from typing import List


# @lc code=start
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        min_price, max_profit = prices[0], 0
        for i in range(1, len(prices)):
            max_profit = max(max_profit, prices[i] - min_price)
            min_price = min(min_price, prices[i])
        return max_profit


# @lc code=end
class SlowSolution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        res = 0
        for i in range(n):
            for j in range(i + 1, n):
                res = max(res, prices[j] - prices[i])
        return res


class TestSolution(unittest.TestCase):
    def setUp(self):
        self.s = Solution().maxProfit

    def test_example1(self):
        self.assertEqual(self.s([7, 1, 5, 3, 6, 4]), 5)

    def test_example2(self):
        self.assertEqual(self.s([7, 6, 4, 3, 1]), 0)


if __name__ == "__main__":
    unittest.main()

#
# @lc app=leetcode id=121 lang=python3
#
# [121] Best Time to Buy and Sell Stock
#
# https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/
#
# algorithms
# Easy (52.31%)
# Likes:    9753
# Dislikes: 399
# Total Accepted:    1.4M
# Total Submissions: 2.8M
# Testcase Example:  '[7,1,5,3,6,4]'
#
# You are given an array prices where prices[i] is the price of a given stock
# on the i^th day.
#
# You want to maximize your profit by choosing a single day to buy one stock
# and choosing a different day in the future to sell that stock.
#
# Return the maximum profit you can achieve from this transaction. If you
# cannot achieve any profit, return 0.
#
#
# Example 1:
#
#
# Input: prices = [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.
# Note that buying on day 2 and selling on day 1 is not allowed because you
# must buy before you sell.
#
#
# Example 2:
#
#
# Input: prices = [7,6,4,3,1]
# Output: 0
# Explanation: In this case, no transactions are done and the max profit =
# 0.
#
#
#
# Constraints:
#
#
# 1 <= prices.length <= 10^5
# 0 <= prices[i] <= 10^4
#
#
#
import unittest
from typing import List


# @lc code=start
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        min_price, max_profit = prices[0], 0
        for i in range(1, len(prices)):
            max_profit = max(max_profit, prices[i] - min_price)
            min_price = min(min_price, prices[i])
        return max_profit


# @lc code=end
class SlowSolution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        res = 0
        for i in range(n):
            for j in range(i + 1, n):
                res = max(res, prices[j] - prices[i])
        return res


class TestSolution(unittest.TestCase):
    def setUp(self):
        self.s = Solution().maxProfit

    def test_example1(self):
        self.assertEqual(self.s([7, 1, 5, 3, 6, 4]), 5)

    def test_example2(self):
        self.assertEqual(self.s([7, 6, 4, 3, 1]), 0)


if __name__ == "__main__":
    unittest.main()

# # @lc app=leetcode id=121 lang=python3 # # [121] Best Time to Buy and Sell Stock # # https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/ # # algorithms # Easy (52.31%) # Likes:    9753 # Dislikes: 399 # Total Accepted:    1.4M # Total Submissions: 2.8M # Testcase Example:  '[7,1,5,3,6,4]' # # You are given an array prices where prices[i] is the price of a given stock # on the i^th day. # # You want to maximize your profit by choosing a single day to buy one stock # and choosing a different day in the future to sell that stock. # # Return the maximum profit you can achieve from this transaction. If you # cannot achieve any profit, return 0. # # # Example 1: # # # Input: prices = [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. # Note that buying on day 2 and selling on day 1 is not allowed because you # must buy before you sell. # # # Example 2: # # # Input: prices = [7,6,4,3,1] # Output: 0 # Explanation: In this case, no transactions are done and the max profit = # 0. # # # # Constraints: # # # 1 <= prices.length <= 10^5 # 0 <= prices[i] <= 10^4 # # # # @lc code=start # @lc code=end