前端练习51 旋转数组

一个旋转问题的练习题。

题目

题目来自LeetCode

给定一个数组,它的第i个元素是一支给定股票第i天的价格。

设计一个算法来计算你所能获取的最大利润。你可以==尽可能地完成更多的交易==(多次买卖一支股票)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:

1
2
3
4
输入: [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,这笔交易所能获得利润 = 6-3 = 3 。

示例 2:

1
2
3
4
5
输入: [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。

示例 3:

1
2
3
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

实现

一开始觉得这是一个动态规划的问题,要拆成另两个部分,买的位置和卖的位置,想了半天,发现没有必要这么复杂

这里的关键是,==尽可能多的完成交易==,比如[1, 3, 2, 3, 4, 5],肯定是两次交易3-15-2的利润比一次交易5-1的利润要高

其实计算的是差价,只要当前的利润小于已有利润,就卖出,已有利润计入当前利润中,并重置相关的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function (prices) {
let buyIndex = 0;
let currentProfit = 0;
let totalProfit = 0;
for (let i = 0; i < prices.length; i++) {
let tempProfit = prices[i + 1] - prices[buyIndex];
if (tempProfit > currentProfit) {
currentProfit = tempProfit
} else {
totalProfit += currentProfit;
currentProfit = 0;
buyIndex = i + 1
}
}
return totalProfit + currentProfit;
};

再查看他人的答案,有更简单的,不像上面积攒到每次交易才算最后的利润值,还需要重置,可以直接每两次的股票差价进行比较,只要利润大于零就计入总利润,否则就抛弃

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function (prices) {
let totalProfit = 0;
let tempProfit = 0;

for (let i = 1; i < prices.length; i++) {
tempProfit = prices[i] - prices[i - 1];
if (prices[i] - prices[i - 1] > 0) {
totalProfit += tempProfit
}
}
return totalProfit;
};

简单多了。