题目描述
假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?
我的思路
暴力寻找最大值。结果用了两层循环,超慢。
我的代码
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function(prices) {
let inPrices=0,outPrices=0,money=0,max=0;
let rec=[];
for(let i=0;i<prices.length;i++)
{
inPrices=prices[i];
for(let j=i+1;j<prices.length;j++)
{
outPrices=prices[j];
money=outPrices-inPrices;
max=Math.max(...rec);
if(money>0&&money>max)
{
rec.push(money);
}
}
}
if(rec.length==0)
{
return 0;
}
max=Math.max(...rec);
return max;
};
复杂度分析
好像应该是n^2。。
优化题解
“在题目中,我们只要用一个变量记录一个历史最低价格 minprice,我们就可以假设自己的股票是在那天买的。那么我们在第 i 天卖出股票能得到的利润就是 prices[i] - minprice。
因此,我们只需要遍历价格数组一遍,记录历史最低点,然后在每一天考虑这么一个问题:如果我是在历史最低点买进的,那么我今天卖出能赚多少钱?当考虑完所有天数之时,我们就得到了最好的答案。”
如果直接找到数组的最小值,往后找最大利润的话,可能会存在最大利润出现在最小值前面的情况,如数组【2,4,1】。所以要边找最小的那天,边找最大利润。
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function(prices) {
let outPrices=0,money=0,min=0;
if(prices.length==0)
{
return 0;
}
min=prices[0];
for(let i=1;i<prices.length;i++)
{
if(prices[i]<min)
{
min=prices[i];
}
else{
outPrices=prices[i];
money=Math.max(outPrices-min,money);
}
}
return money;
};
再简洁一点就是官方的这种写法
var maxProfit = function(prices) {
let minprice = Number.MAX_VALUE;
let maxprofit = 0;
for (const price of prices) {
maxprofit = Math.max(price - minprice, maxprofit);
minprice = Math.min(price, minprice);
}
return maxprofit;
};
其中Number.MAX_VALUE
属性表示在 JavaScript 里所能表示的最大数值。
MAX_VALUE
属性值接近于1.79E+308
。大于MAX_VALUE
的值代表 "Infinity
"。因为
MAX_VALUE
是Number
对象的一个静态属性,所以你应该直接使用Number.MAX_VALUE
,而不是作为一个创建的Number
实例的属性。
这题还能用动态规划做,但是大体思路是跟这个一次遍历差不多的。