给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。
注意你不能在买入股票前卖出股票。
个人认为的注意点:最多允许完成一次交易
示例一:
输入: [7, 1, 5, 3, 4, 6]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。
示例二:
输入: [7, 6, 4, 3, 1]
输出: 0
解释:没有交易,最大利润就是0
解题思路 0 ——暴力法
维护一个maxProfit变量,遍历数组中的每一项,然后跟该项后面的项进行利润比较,如果利润大于当前的最大利润,则更新之
时间复杂度: O(n^2)
空间复杂度:O(1)
编码实现
function maxProfit (arr) {
var maxProfit = 0
for (var i = 0; i < arr.length; ++i) {
for (var j = i+1; j < arr.length; ++j) {
if (arr[j] - arr[i] > maxProfit) {
maxProfit = arr[j] - arr[i]
}
}
}
return maxProfit
}
解题思路1:一次遍历法:
维护两个变量:
maxProfit
(初值为0)和minprice
(初值为无限大) ,然后遍历数组,如果当前项小于我们维护的最小值,则更新最小值为当前项的值,然后,判断当前项减去最小值是否大于maxProfit
,如果大于,则更新之
编码实现
function maxProfit (arr) {
let maxProfit = 0, minPrice = Infinity
arr.forEach((item) => {
if (item < minPrice) {
minPrice = item
}
if (item - minPrice > maxProfit) {
maxProfit = item - minPrice
}
})
}
解题思路2:一次遍历
维护两个变量,一个是当前的利润值
currentProfit
,一个是最高的利润值maxProfit
遍历数组,当前利润加上用后一项的值减去当前值的值 ,如果当前利润值小于零,我们则将当前利润值归零。否则,不作处理。下一步,如果当前利润值大于最高的利润值,则更新最高利润值为当前值
编码实现:
function maxProfit (arr) {
let currentProfit = 0, maxProfit = 0
for (let i = 0; i < arr.length - 1; ++i) {
currentProfit += arr[i+1] - arr[i]
if (currentProfit < 0) {
currentProfit = 0
}
if (currentProfit > maxProfit) {
maxProfit = currentProfit
}
}
}