思路
暴力法
从左到右遍历每一位数字(除最后一位,直接为0),从他的下一位开始,寻找第一个比他大的数。
时间复杂度为O(N2),超时。
class Solution(object):
def dailyTemperatures(self, T):
while not T:
return []
n = len(T)
res = []
for i in range(n-1):
for j in range(i+1,n):
if T[j] > T[i]:
res.append(j-i)
break
elif j == n -1:
res.append(0)
res.append(0)
return res
暴力法优化
我们发现,从左到右遍历,进行搜索的时候会有很大的重复搜索区域,如下图:
那么我们可以从右向左遍历,计算过的位置就不需要重复计算
当我们想计算75位置时,向右搜索到71位置,71<75,且该位置已经算过了,为2,表示71后2位的数字才比71大,那么此时我们就可以直接跳2位,再与75进行比较。当下一位不大于当前位 且计算结果为0时,这一位可以直接赋0。
class Solution(object):
def dailyTemperatures(self, T):
while not T:
return []
n = len(T)
res = [0] * n
for i in range(n-2,-1,-1): #从右向左遍历
j = i + 1
while j <= n-1:
if T[j] > T[i]:
res[i] = j - i
break
elif res[j] == 0:
res[i] = 0
break
j += res[j] #每次跳res[j]位
return res
单调递减栈的做法
class Solution:
def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
# 单调递减栈:寻找右边第一个比他大的位置
stack = [0]
res = [0] * len(temperatures)
for i in range(1, len(temperatures)):
# 小于和等于栈顶元素,直接入栈
if temperatures[i] <= temperatures[stack[-1]]:
stack.append(i)
else:
# 持续维护单调递减栈
# 大于栈顶元素,说明是右边大于栈顶元素的第一个元素,直接计算距离
while stack and temperatures[i] > temperatures[stack[-1]]:
res[stack[-1]] = i - stack[-1]
stack.pop()
stack.append(i)
return res