# 121. 买卖股票的最佳时机
# 题目
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润。
注意:你不能在买入股票前卖出股票。
例
输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。 注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
# 题解
# 遍历
遍历数组,记录之前的最低价格,计算差价
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function(prices) {
let min = prices[0];
let ans = 0;
for (let i = 0; i < prices.length; ++i) {
const cur = prices[i];
if (cur < min) {
min = cur;
} else {
ans = Math.max(cur - min, ans);
}
}
return ans;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
时间复杂度: O(n)
空间复杂度: O(1)
# 动态规划
状态 dp[i] 表示第 i 天的最大利润
转移方程:
- 第
i天操作dp[i] = A[i] - min(0,..i-1)第i价格减去之前的最低价 - 不操作
dp[i] = dp[i-1]
=> dp[i] = max(dp[i-1], A[i]-min(0,...,i-1))
边界条件: dp[0] = 0
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function(prices) {
if (prices.length == 0) return 0;
let dp = [0];
let min = prices[0];
for (let i = 1; i < prices.length; ++i) {
dp[i] = Math.max(dp[i - 1], prices[i] - min);
min = Math.min(prices[i], min);
}
return dp[prices.length - 1];
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
实际只依赖最近的两个状态,进行存储优化
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function(prices) {
if (prices.length == 0) return 0;
let a = 0,
b = 0;
let min = prices[0];
for (let i = 1; i < prices.length; ++i) {
b = Math.max(a, prices[i] - min);
a = b;
min = Math.min(prices[i], min);
}
return b;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16