[LeetCode] 901. Online Stock Span 股票价格跨度
Write a class StockSpanner which collects daily price quotes for some stock, and returns the span of that stock's price for the current day.
The span of the stock's price today is defined as the maximum number of consecutive days (starting from today and going backwards) for which the price of the stock was less than or equal to today's price.
For example, if the price of a stock over the next 7 days were [100, 80, 60, 70, 60, 75, 85], then the stock spans would be [1, 1, 1, 2, 1, 4, 6].
Example 1:
Input: ["StockSpanner","next","next","next","next","next","next","next"], [[],[100],[80],[60],[70],[60],[75],[85]]
Output: [null,1,1,1,2,1,4,6]
Explanation:
First, S = StockSpanner() is initialized. Then:
S.next(100) is called and returns 1,
S.next(80) is called and returns 1,
S.next(60) is called and returns 1,
S.next(70) is called and returns 2,
S.next(60) is called and returns 1,
S.next(75) is called and returns 4,
S.next(85) is called and returns 6.
Note that (for example) S.next(75) returned 4, because the last 4 prices
(including today's price of 75) were less than or equal to today's price.
Note:
- Calls to
StockSpanner.next(int price)will have1 <= price <= 10^5. - There will be at most
10000calls toStockSpanner.nextper test case. - There will be at most
150000calls toStockSpanner.nextacross all test cases. - The total time limit for this problem has been reduced by 75% for C++, and 50% for all other languages.
这道题定义了一个 StockSpanner 的类,有一个 next 函数,每次给当天的股价,让我们返回之前连续多少天都是小于等于当前股价。跟 OJ 抗争多年的经验告诉我们,不要想着可以用最暴力的向前搜索的方法,这种解法太 trivial 了,肯定无法通过的。那么可以找连续递增的子数组的长度么,其实也是不行的,就拿题目中的例子来说吧 [100, 80, 60, 70, 60, 75, 85],数字 75 前面有三天是比它小的,但是这三天不是有序的,是先增后减的,那怎么办呢?我们先从简单的情况分析,假如当前的股价要小于前一天的,那么连续性直接被打破了,所以此时直接返回1就行了。但是假如大于等于前一天股价的话,情况就比较 tricky 了,因为此时所有小于等于前一天股价的天数肯定也是小于等于当前的,那么我们就需要知道是哪一天的股价刚好大于前一天的股价,然后用这一天的股价跟当前的股价进行比较,若大于当前股价,说明当前的连续天数就是前一天的连续天数加1,而若小于当前股价,我们又要重复这个过程,去比较刚好大于之前那个的股价。所以我们需要知道对于每一天,往前推刚好大于当前股价的是哪一天,用一个数组 pre,其中 pre[i] 表示从第i天往前推刚好大于第i天的股价的是第 pre[i] 天。接下来看如何实现 next 函数,首先将当前股价加入 nums 数组,然后前一天在数组中的位置就是 (int)nums.size()-2。再来想想 corner case 的情况,假如当前是数组中的第0天,前面没有任何股价了,我们的 pre[0] 就赋值为 -1 就行了,怎么知道当前是否是第0天,就看 pre 数组是否为空。再有就是由于i要不断去 pre 数组中找到之前的天数,所以最终i是有可能到达 pre[0] 的,那么就要判断当i为 -1 时,也要停止循环。循环的最后一个条件就是当之前的股价小于等当前的估计 price 时,才进行循环,这个前面讲过了,循环内部就是将 pre[i] 赋值给i,这样就完成了跳到之前天的操作。while 循环结束后要将i加入到 pre 数组,因为这个i就是从当前天往前推,一个大于当前股价的那一天,有了这个i,就可以计算出连续天数了,参见代码如下:
解法一:
class StockSpanner {
public:
StockSpanner() {}
int next(int price) {
nums.push_back(price);
int i = (int)nums.size() - 2;
while (!pre.empty() && i >= 0 && nums[i] <= price) {
i = pre[i];
}
pre.push_back(i);
return (int)pre.size() - 1 - i;
}
private:
vector<int> nums, pre;
};
我们还可以使用栈来做,里面放一个 pair 对儿,分别是当前的股价和之前比其小的连续天数。在 next 函数中,使用一个 cnt 变量,初始化为1。还是要个 while 循环,其实核心的本质都是一样的,循环的条件首先是栈不能为空,并且栈顶元素的股价小于等于当前股价,那么 cnt 就加上栈顶元素的连续天数,可以感受到跟上面解法在这里的些许不同之处了吧,之前是一直找到第一个大于当前股价的天数在数组中的位置,然后相减得到连续天数,这里是在找的过程中直接累加连续天数,最终都可以得到正确的结果,参见代码如下:
解法二:
class StockSpanner {
public:
StockSpanner() {}
int next(int price) {
int cnt = 1;
while (!st.empty() && st.top().first <= price) {
cnt += st.top().second; st.pop();
}
st.push({price, cnt});
return cnt;
}
private:
stack<pair<int, int>> st;
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/901
参考资料:
https://leetcode.com/problems/online-stock-span/
https://leetcode.com/problems/online-stock-span/discuss/168311/C%2B%2BJavaPython-O(1)
[LeetCode All in One 题目讲解汇总(持续更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)
[LeetCode] 901. Online Stock Span 股票价格跨度的更多相关文章
- [LeetCode] 901. Online Stock Span 线上股票跨度
Write a class StockSpanner which collects daily price quotes for some stock, and returns the span of ...
- leetcode 901. Online Stock Span
Write a class StockSpanner which collects daily price quotes for some stock, and returns the span of ...
- LC 901. Online Stock Span
Write a class StockSpanner which collects daily price quotes for some stock, and returns the span of ...
- 【LeetCode】901. Online Stock Span 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 单调递减栈 日期 题目地址:https://leet ...
- 【leetcode】901. Online Stock Span
题目如下: 解题思路:和[leetcode]84. Largest Rectangle in Histogram的核心是一样的,都是要找出当前元素之前第一个大于自己的元素. 代码如下: class S ...
- 901. Online Stock Span [短于线性的时间统计单个元素的Span ]
Span 指这个元素之前连续的小于这个元素的值有多少个 原理: 维护递减栈 这个栈内的元素是递减的序列 新到一个元素x 依次出栈比x小的(也就是这个元素的Span) 这种问题的关键在于 新来的元素如果 ...
- Elasticsearch Span Query跨度查询
ES基于Lucene开发,因此也继承了Lucene的一些多样化的查询,比如本篇说的Span Query跨度查询,就是基于Lucene中的SpanTermQuery以及其他的Query封装出的DSL,接 ...
- [Swift]LeetCode901. 股票价格跨度 | Online Stock Span
Write a class StockSpanner which collects daily price quotes for some stock, and returns the span of ...
- [leetcode/lintcode 题解] 微软面试题:股票价格跨度
编写一个 StockSpanner 类,它收集某些股票的每日报价,并返回该股票当日价格的跨度. 今天股票价格的跨度被定义为股票价格小于或等于今天价格的最大连续日数(从今天开始往回数,包括今天). 例如 ...
随机推荐
- 【UOJ#76】【UR #6】懒癌(动态规划)
[UOJ#76][UR #6]懒癌(动态规划) 题面 UOJ 题解 神....神仙题. 先考虑如果是完全图怎么做... 因为是完全图,所以是对称的,所以我们只考虑一个有懒癌的人的心路历程. 如果只有一 ...
- sysstat工具包之mpstat
mpstat 1 简介 mpstat是一个实时监控工具,主要报告与CPU相关统计信息,信息存放在/proc/stat文件中: 在多核心cpu系统中,不仅可以查看cpu平均信息,还可以查看指定cpu信息 ...
- open*** 搭建
pptp 互联网上服务商给拦截.不稳定. opevpn 1.为了保证OpenVPN的安装,需要使用easy-rsa秘钥生成工具生成证书 [root@m01 ~]# yum install easy-r ...
- Mybatis插入实体类字段为关键字解决方案
1. Mybatis插入实体类字段为关键字解决方案 1.1. 前言 可能你插入字段为关键字时报如下错误,且字段名不适合改变 You have an error in your SQL syntax; ...
- SpringBoot结合策略模式实战套路
1. SpringBoot结合策略模式实战套路 1.1. 前言 我们都知道设计模式好,可以让我们的代码更具可读性,扩展性,易于维护,但大部分程序猿一开始都学过至少一遍设计模式吧,实战中不知用到了几成. ...
- NBIOT实现UDP协议的发送和接收(包含软件升级)
源码下载: nbiot_module程序(java netbean) -> 提取码 UdpServer程序(C# vs2010) -> 提取码 QQ:505645074 前提条件:开NB卡 ...
- ptrace函数深入分析
ptrace函数:进程跟踪. 形式:#include<sys/ptrace.h> Int ptrace(int request,int pid,int addr,int data); 概述 ...
- jQuery中的index用法与inArray用法
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- Vue+ElementUI 安装与应用
1.初始化创建一个vue项目: 打开终端输入命令 vue init webpack vueui ---------------------------------- ? Project name my ...
- Tomcat 配置介绍
参数说明: maxThreads: 最大可以创建请求的线程数 minSpareThreads: 服务启动时创建的处理请求的进程数 Connector中的port: 创建服务器端的端口号,此端口监听用户 ...