(leetcode739)每日温度(暴力法及其改进,巧妙使用栈)

leetcode第739题,原题如下:
在这里插入图片描述

一、首先想到的是O(n2)暴力法

对于每一个元素都向后遍历,直到找到第一个比当前元素大的位置,记录距离差。

class Solution:
    def dailyTemperatures(self, T: List[int]) -> List[int]:
        l=len(T)
        lst=[0]*l
        for index in range(l):
            for j in range(index+1,l):
                if T[j]>T[index]:
                    lst[index]=j-index
                    break
        return lst

超时,时间复杂度太高。

二、基于暴力法的改进,复杂度为O(nlogn)

读一遍列表,因为只有30-100这71个数字,为了方便可以分别设置101个列表,将每个元素的索引都对应在这个元素的列表里。
例如[41,42,42,44]对应的列表为[[]…[],[0],[1,2],[],[3],[]…[]];
(其中,[0]对应的下标为41,[1,2]对应的下标为42,[3]对应的下标为44。)
遍历温度表,以index=2的数字75为例,先到76对应的列表中找索引大于2的最小值p,使lst[index]=min(lst[index],p-index),找完76–101这26个数组中的最小距离,就是我们需要的距离。

class Solution:
    def dailyTemperatures(self, T: List[int]) -> List[int]:
        l=len(T)
        lst=[[] for _ in range(101)]
        #为了后边min可以顺利起作用,把初值设为比最长距离30000还大的40000
        ret=[40000]*l
        for index in range(l):
            lst[T[index]].append(index)
        for index in range(l):
            i=1
            while 30<T[index]+i<101:
                if not lst[T[index]+i]:
                    i+=1
                    continue
                #二分找最小位置
                t=lst[T[index]+i]
                left,right=0,len(t)-1
                loc=right
                while left<=right:
                    mid=(left+right)//2
                    if t[mid]>index:
                        loc=mid
                        right=mid-1
                    else:
                        left=mid+1
                #print(t[loc],loc)
                if t[loc]>index:
                    ret[index]=min(ret[index],t[loc]-index)
                i+=1
        for index in range(len(ret)):
            ret[index]=0if ret[index]==40000else ret[index]
        return ret

时间复杂度仍较高,超时。
(笔者感觉这个复杂度也可以了,应该是代码水平不行所以超时)

三、使用栈,O(n)复杂度

这是笔者学习大神‘程序员吴师兄’的思路写的代码,原文链接,视频讲解非常清楚,膜拜辽。

思路是维护一个上小下大的单调栈。
栈初始值为元组(0,T[0])。
对于后面每一个元素new,如果他大于栈顶元素t,表明栈顶元素t遇到了第一个比t高的温度,则t出栈,将ret[t[0]]位置记录为index-t[0](即new和t之间的距离差)。
遍历至终点,没有遇到更大元素的位置仍为初始值0。

class Solution:
    def dailyTemperatures(self, T: List[int]) -> List[int]:
        ret=[0]*len(T)
        stack=[(0,T[0])]
        for index in range(1,len(T)):
            while stack and T[index]>stack[-1][1]:
                t=stack.pop(-1)
                ret[t[0]]=index-t[0]
            stack.append((index,T[index]))
        return ret
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值