题目
概述:给定一个股票每日价格列表,返回股票价格的跨度:从当天开始往回数小于等于今天价格的最大连续日数(包括今天)
思路
第一天的股票价格跨度为1
-
第N天的股票价格跨度为:
- 第N天的股票价格 >= 第(N - 1)天的股票价格 => 第(N - 1)天的股票价格跨度 + 1 + :
- 第(N - 1 - 第(N - 1)天的价格跨度)天的股票价格不存在 => 0
- 第(N - 1 - 第(N - 1)天的价格跨度)天的股票价格 > 第N天的股票价格 => 0
- 第(N - 1 - 第(N - 1)天的价格跨度)天的股票价格 <= 第N天的股票价格 => 第(N - 1 - 第(N - 1)天的价格跨度)天的股票价格跨度,并继续循环
- 第N天的股票价格 < 第(N - 1)天的股票价格 => 1
- 第N天的股票价格 >= 第(N - 1)天的股票价格 => 第(N - 1)天的股票价格跨度 + 1 + :
-
依次类推,可以得到每一天的股票价格跨度
特殊case:(4,5,6,0,0,0,0,0,8),0无限多的情况会导致一次调用next的时长耗时O(n),解决方案是用一个变量记录之前遇到的最大的数,如果当前股票价格大于等于记录的最大的数,则可以直接跳到该最大的数的位置做后续的运算
代码
class StockSpanner {
private List<Stock> list = new ArrayList<>();
//record maxIndex to fast skip continue small number like such case (4,5,6,0,0,0,0,0,8)
private int maxIndex;
public StockSpanner() {
}
public int next(int price) {
Stock stock = new Stock();
int size = list.size();
if (size == 0) {
stock.span = 1;
} else {
if (price >= list.get(size - 1).price) {
int index = size - 1;
stock.span = 1;
if (price >= list.get(maxIndex).price) {
stock.span += index - maxIndex;
index = maxIndex;
}
do {
stock.span += list.get(index).span;
index -= list.get(index).span;
} while (index >= 0 && price >= list.get(index).price);
maxIndex = size;
} else {
stock.span = 1;
}
}
stock.price = price;
list.add(stock);
return stock.span;
}
private class Stock {
int span;
int price;
}
}