题目
题目链接:leetcode-cn.com/leetbook/re…
题解
1、动态规划的分析
价格数组为 prices
1、划分子问题,确定子问题的边界
- 设天数为 i 的问题的最大利润为 maxProfit[i] , 则天数为 i+1 的问题的最大利润为 maxProfit[i+1] = Max( maxProfit[i] , prices[i+1]-minPrice )
2、定义优化函数,列出优化函数的递推方程,判断其是否满足优化原则
根据递推方程(状态转移方程),n 天的最大利润由 n-1 天的最大利润决定; 所以其满足优化原则,可以使用动态归划;
3、编程
具体程序实现如下;
2、动态归划(DP)
如上分析,可得到如下程序:
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function(prices) {
const len = prices.length;
let minPrice = prices[0],
f = [0];
if(len < 2) {
return 0;
}
for(let i = 1;i < len;i++) {
f[i] = Math.max(f[i-1],prices[i] - minPrice);
if(minPrice > prices[i]) {
minPrice = prices[i];
}
}
return f[len - 1];
};
对程序进行时空优化;
2.1、优化时间
上面的循环中的循环体为:
方法一:
// 一个计算操作,一个比较操作,一个赋值操作
f[i] = Math.max(f[i-1],prices[i] - minPrice);
// 一个比较操作
if(minPrice > prices[i]) {
// 一个赋值操作
minPrice = prices[i];
}
方法二:
// 一个比较操作
if(minPrice > prices[i]) {
// 两个赋值操作
minPrice = prices[i];
f[i] = f[i-1];
}else {
// 一个计算操作,一个比较操作,一个赋值操作
f[i] = Math.max(f[i-1],prices[i] - minPrice);
}
方法一最少4个操作,最多5个操作; 方法二最少3个操作(并且是更省时的赋值操作),最多4个操作;
理论上来讲,对于同规模的一个问题,方法一会比方法二的用时少;
2.2、优化空间
在上面的程序中,空间消耗主要花费在存储存储问题的的解的数组上,空间复杂度为 O(n),但是分析代码可知,计算 f(n) 时只需要知道 f(n-1) ,i < n-1 的 f(i) 并不需要知道; 于是可以只用一个变量存储子问题的最大利润;
算法如下:
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function(prices) {
const len = prices.length;
let minPrice = prices[0],
maxPro = 0;
if(len < 2) {
return 0;
}
for(let i = 1;i < len;i++) {
maxPro = Math.max(maxPro,prices[i] - minPrice);
if(minPrice > prices[i]) {
minPrice = prices[i];
}
}
return maxPro;
};
3、暴力枚举法
时间消耗太大,程序可以运行,但是 leetcode 提交超出时间限制;
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function(prices) {
// 双重循环,外层遍历选定某个值,内层遍历找到选定值后的所有值中的最大值,使用变量记录利润
let max = 0;
let temp = 0;
let tempMax = 0,
tempj = 0;
const len = prices.length;
for(let i = 0;i < len;i++) {
temp = prices[i];
for(let j = i + 1;j < len;j++) {
tempj = prices[j];
if(temp < tempj) {
temp = tempj;
}
}
tempMax = temp - prices[i];
if(max < tempMax) {
max = tempMax;
}
}
return max;
};
大家如果有更好的思路和解法,欢迎大家一起来讨论啊~
这是使用 JavaScript 对 LeetCode《初级算法》的每道题的总结和实现的其中一篇,汇总篇在这里: