一、题目描述
二、思路分析:
分析题目:求一个数组中两个值之间的最大差值。
再看限制条件:差值必须是后一个位置减去前一个位置,如果小于 0,则返回 0,
最简单暴力循环,通过两层循环,可以实现对所有的差值进行比较。次数为 n(n-1)/2
var maxProfit = function (prices) {
let max = 0;
for (let i = 0; i < prices.length - 1; i++) {
for (let j = i + 1; j < prices.length; j++) {
const diff = prices[j] - prices[i];
// 错误记录:第一次忘了写 max,不是一次通过
max = Math.max(max, diff);
}
}
return max;
};
存在问题:当数组长度过长,报错:运行超出时间限制
- 时间复杂度:O(n^2);比较了
n(n-1)/2
次; - 空间复杂度:O(1);
为什么是
n(n-1)/2
?(n-1) + (n-2) + (n-3) ... + 1
, 构造一个相同的正向序列来计算,1 + 2 + ... (n-1)
, 两个式子取和为n + n ...n
, 一共为n-1
个,写为n(n-1)
, 除去2
为原式的值n(n-1)/2
。所以比较了n(n-1)/2
次。就是高斯求和的思想。
换一个思路理解,如果我们在第i
天需要获得最大的利润,那么一定是减去在之前[0, i-1]
个元素中的最低价格从而得到最大的利润。所以在遍历的时候可以通过一个变量记录遍历过程中最小的数。最大利润:当前价格-历史最低价格。
var maxProfit = function (prices) {
let minPrice = Infinity;
let maxProfit = 0;
for (let i = 0; i < prices.length; i++) {
if (prices[i] < minPrice) {
minPrice = prices[i];
} else if (maxProfit < prices[i] - minPrice) {
maxProfit = prices[i] - minPrice
}
}
return maxProfit;
};
- 时间复杂度:O(n);
- 空间复杂度:O(1);
三、总结:
本题的关键是思考的方向,在做算法题的时候多换几个方向思考,不用一言不合就上暴力,感觉当你进入暴力之后,思维就会逐渐固化,往这个方向去想,很难想到更好的方法了。而是应该在最开始的时候分析题目是什么类型,然后按照类型进行思考划分,是否能够这样解决。
本题是股票系列里面最简单的一道题,本次学习计划先把股票系列问题解决掉。加油!