网址:https://leetcode.com/problems/Best-Time-to-Buy-and-Sell-Stock/
第一想法是滑动窗口法,稍微尝试后发现不可行,至少我不会。。。
而后想到动态规划,进一步思考发现完全可行:
index | 0 | 1 | 2 | 3 | 4 | 5 |
price[] | 7 | 1 | 5 | 3 | 6 | 4 |
dp[] | 0 | 0 | 4 | 2 | 5 | 3 |
price[index-1] - dp[index-1] | 0 | 0 | 1 | 1 | 1 | 1 |
状态:dp[i] 表示prices[]从 0 到 i 这部分的最大利润
状态转移方程:
dp[i] = max(0, prices[i] - (prices[i-1] - dp[i-1]));
使用dp数组的代码如下:
class Solution { public: int maxProfit(vector<int>& prices) { int ans = 0; vector<int> dp(prices.size(), 0); for(int i=1; i<prices.size();i++) { dp[i] = max(0, prices[i] - (prices[i-1] - dp[i-1])); ans = max(dp[i], ans); } return ans; } };
然而,dp数组会占用多余的空间。我们知道,一位dp问题的dp数组的赋值往往可以转化为几个变量之间的循环赋值的过程
所以,改进如下:
class Solution { public: int maxProfit(vector<int>& prices) { if(prices.size() == 0) { return 0; } int ans = 0; int res = 0; int pre_price = prices[0]; int pre_dp = 0; for(int price : prices) { res = max(0, price - (pre_price - pre_dp)); pre_dp = res; pre_price = price; ans = max(res, ans); } return ans; } };
注意,用这种方式要先判断size是否为0,否则会出现Runtime Error。。。
两份代码的Runtime都是8ms,而改进后内存占用由9.7MB减少到9.5MB,千万别小看这0.2MB。
我们从击败5%的同学升级到击败46%的同学!