leetcode 901. 股票价格跨度(单调栈解法详解)

一、注

如果您还不知道什么是单调栈;如果你想要了解leetcode中单调栈题目的汇总,可以看博主的这篇博客。

       何谓单调栈?leetcode单调栈题目汇总

 

二、原题

原题链接 901. 股票价格跨度

编写一个 StockSpanner 类,它收集某些股票的每日报价,并返回该股票当日价格的跨度。

今天股票价格的跨度被定义为股票价格小于或等于今天价格的最大连续日数(从今天开始往回数,包括今天)。

例如,如果未来7天股票的价格是 [100, 80, 60, 70, 60, 75, 85],那么股票跨度将是 [1, 1, 1, 2, 1, 4, 6]。

来源:力扣(LeetCode)

 

三、解析

维持一个单减栈min_stack,栈中的元素是索引值,而不是股票的价格;同时创建一个数组days,days[i]就表示股票价格小于等于第i天股票价格的最大连续天数。当遍历到索引为index的元素时,将第index天的股票价格num[index]与栈顶索引对应的股票价格num[min_stack[-1]]进行对比,每次进行出栈操作时,我们不仅需要给days[index] + 1(因为出栈一次,表明栈顶索引对应的股票价格小于第index天的股票价格),还应该将days[min_stack[-1]]的值累加到days[index],这样才能计算出最大连续天数。以num = [100, 80, 60, 70, 60, 75, 85]为例,初始化days的元素值全为0

第一天时,num[0] = 100, 此时栈空,故将索引0入栈,days[0] = 0

第二天时,num[1] = 80, 栈顶索引为0,num[0]=100 > 80,故将索引1入栈,days[1]=0

第三天数,num[2] = 60,栈顶索引为1,num[1]=80 > 60,故将索引2入栈,days[2] = 0

第四天数,num[3] = 70,栈顶索引为2,num[2]=60 < 70,故将索引2出栈,每次出栈表示栈顶对应的股票价格低于当天的价格,因此days[3]加一,同时因为求连续天数,我们还要看看60前面有没有比60还小的,有的话需要累加到days[3]上,也就是另days[3] += days[min_stack[-1]] 。2出栈以后,新的栈顶索引为1,num[1] = 80 > 70,故将索引3入栈。此时,栈中元素从栈底到栈顶依次为0、1、3。days[3] = 1。

第五天数,num[4] = 60,栈顶索引为3,num[3]=70 > 60,故将索引4入栈,days[4] = 0

第六天数,num[5] = 75,栈顶索引为4,num[4]=60 < 75,故将索引4出栈,days[5] + 1 变为1 days[5] + days[4] = 1 + 0 = 1;新的栈顶为3,num[3]=70<75,days[5]+1变为2,days[5] + days[3] = 2 + 1 = 3;新的栈顶为2,num[2] = 80 > 75,故将5入栈

第七天数,num[6] = 85,栈顶索引为5,num[5]=75 < 85,故将索引5出栈,days[6] + 1 = 0 + 1 = 1, days[6] + days[5] = 1 + 3 = 4;新的栈顶为2,num[2] = 80 < 85, days[6] + 1 = 4 + 1 = 5, days[6] + days[2] = 5 + 0 = 5。新的栈顶元素为0,num[0] = 100 > 85.。将6入栈。

遍历结束,此时,days的元素值为[0,0,0,1,0,3,5]。最后因为题目要求小于等于今天(包括今天),因此将days中的值全部加1便得到最终结果。

上述过程比较详细,因此代码就不再添加注释了。

def Stock(num):
    length = len(num)
    min_stack = []
    days = [0] * length
    for index in range(length):
        while(min_stack and num[min_stack[-1]] <= num[index]):
            days[index] += days[min_stack[-1]]
            min_stack.pop()
            days[index] += 1

        min_stack.append(index)
    days = [val+1 for val in days]
    return days

上述代码只是我在自己电脑上的测试。leetcode上需要提交的代码如下。注,与上述代码不同的是,下面的代码中,单减栈的元素是一个元组(price, days),表示某天的价格为price,小于等于该天股票价格的最大连续天数为days。

class StockSpanner:

    def __init__(self):
        self.min_stack = []   # 维持一个单减栈
         
    def next(self, price: int) -> int:
        days = 1      # 因为是小于等于今天,故将days的值初始化为1.
        while(self.min_stack and self.min_stack[-1][0] <= price):
            days += self.min_stack[-1][1]
            self.min_stack.pop()
        self.min_stack.append((price, days))
        return days



# Your StockSpanner object will be instantiated and called as such:
# obj = StockSpanner()
# param_1 = obj.next(price)

 

你可能感兴趣的:(leetcode刷题,数据结构,leetcode,python)