LeetCode 记录-901. 股票价格跨度

80 阅读1分钟

LeetCode 记录-901. 股票价格跨度

我的解法

思路

image.png

我的思路比较简单,就是往前找比当天价格小的价格,找到后 count++,最后返回 count。

代码

var StockSpanner = function () {
  this.stocks = [];
};

/**
 * @param {number} price
 * @return {number}
 */
StockSpanner.prototype.next = function (price) {
  this.stocks.push(price);
  let count = 0;
  let idx = this.stocks.length - 1;
  while (idx >= 0 && this.stocks[idx] <= price) {
    idx--;
    count++;
  }
  return count;
};

复杂度分析(自我分析,不一定对)

时间复杂度

O(nn)O(n*n),n 为next()函数调用的次数,在最坏情况下,price 是按单调递增出现,那么每次调用都会一直遍历到开头,所以时间复杂度为O(nn)O(n*n)

空间复杂度

O(n)O(n),n 为next()函数调用的次数,栈用来存 price 的空间代价的期望为O(n)O(n)


官方解法: 单调栈

思路

调用next()时,输入的是新的一天的股票价格,需要返回包括此日在内的,往前数最多有连续多少日的股票价格是小于等于今日股票价格的。使用单调栈算法,维护一个包含[天数, price]且 price 单调递减的栈。当添加一个新的 price 时,将以前 price 小于且等于今天 price 的元素全部 pop,然后用今天的天数和最近的一个 price 大于今天 price 的天数算出结果。

代码

var StockSpanner = function () {
  this.stack = [];
  this.stack.push([-1, Number.MAX_VALUE]);
  this.idx = -1;
};

StockSpanner.prototype.next = function (price) {
  this.idx++;
  while (price >= this.stack[this.stack.length - 1][1]) {
    this.stack.pop();
  }
  let ret = this.idx - this.stack[this.stack.length - 1][0];
  this.stack.push([this.idx, price]);
  return ret;
};

复杂度分析

时间复杂度

O(n)O(n),其中 n 为调用 next 函数的次数,每个 price 值最多会出栈、入栈各一次。

空间复杂度

O(n)O(n),栈中最多有 n 个元素。