# Discussion

We can use a state machine to solve this problem. Detail can be found HERE.

We can have 3 actions:

• sell
• do nothing (rest)

If we define s0 as rest, then from s0:

• we can keep on resting,

if we buy, we are transmitting to state s1.

From state 1, we can

• sell
• keep on doing nothing.

If we doing nothing, we will stay at state s1

if we sell, we will go to a new state s2.

From s2, we must go to state s0 to guarantee the cooldown requirement.

The state transition can be visualized here.

# Solution 1

`/*** jimmy shen* time complexity O(n)* space complexity O(n)**/class Solution {public:    int maxProfit(vector<int>& prices) {        const int n = prices.size();        if (n==0) return 0;                vector<vector<int>> dp(n, vector<int>(3, INT_MIN));                dp = 0, dp = -prices;                for (int i = 1; i < n; ++i)        {            /**            * dp[i] is the state of s0 (rest)            * dp[i] is the state of s1 (buy)            * dp[i] is the state of s2 (sell)            **/            dp[i] = max(dp[i-1], dp[i-1]);            dp[i] = max(dp[i-1], dp[i-1] - prices[i]);            dp[i] = dp[i-1] + prices[i];        }        auto ret = max(dp[n-1], dp[n-1]);        return ret == INT_MIN? 0 : ret;    }};`

# Solution 2

An improved O(1) space complexity solution

`/*** jimmy shen* time complexity O(n)* space complexity O(1)**/class Solution {public:    int maxProfit(vector<int>& prices) {        const int n = prices.size();        if (n==0) return 0;                int s0 = 0, s1 = -prices, s2 = INT_MIN;        int new_s0, new_s1, new_s2;        for (int i = 1; i < n; ++i)        {            new_s0 = max(s0, s2);            new_s1 = max(s1, s0 - prices[i]);            new_s2 = s1 + prices[i];            s0 = new_s0, s1 = new_s1, s2 = new_s2;        }        auto ret = max(s0, s2);        return ret == INT_MIN? 0 : ret;    }};`