我正在Daily Temperatures - LeetCode
- 每日温度
给出每日温度列表
T
,返回一个列表,以便对于输入中的每一天,告诉您要等到温暖的温度需要多少天。如果没有将来的可能,请放0
。例如,给定温度列表
T = [73, 74, 75, 71, 69, 72, 76, 73]
,您的输出应为[1, 1, 4, 2, 1, 1, 0, 0]
。注意:
范围内的整数temperatures
的长度将在[1, 30000]
范围内。每个温度都是
分析问题
Given:nums, list a daily temperature, len(nums) < 30000, in range[30, 100] Find:How many days to wait until a warmmer temperature, soonest Requirements: if empty return 0,
具有两个指针(O(n ** 2))的蛮力解决方案
class Solution1:
def dailyTperatures(self, nums: 'List[int]') -> 'List[int]':
res = [0] * len(nums)
for i in range(len(nums)):
for j in range(i, len(nums)):
if nums[j] > nums[i]:
res[i] = j - i
break #guarentee the soonest
return res
重新检查问题,发现没有使用给定条件range[30,100]
官方答案利用了这种情况
计划是使用next array
来存储(记住)温度更高的索引。
class Solution2:
def dailyTemperatures(self, nums):
"""
Runtime: 976 ms, faster than 8.40%
Memory Usage: 16.6 MB, less than 11.02%
"""
nxt = [float('inf')] * 102
res = [0] * len(nums)
for i in range(len(nums) - 1, -1, -1):
#Use 102 so min(nxt[t]) has a default value
j= min(nxt[t] for t in range(nums[i]+1, 102))
if j< float('inf'):
res[i] = j- i
nxt[nums[i]] = i
return res
直到现在,len(nums) < 30000
还剩下一个条件。我检查了所有其他解决方案,但没有发现这种情况是其中的一种用法。
正式的stack
解决方案开头是一个好问题
考虑尝试在
T[i]
查找下一个较暖的事件。我们必须记住哪些信息(关于T[j]
的{{1}})?
该想法是使用堆栈记住温度较高的索引。
j > i
具有相同想法的更优雅的解决方案。
class Solution3:
def dailyTemperatures(self, nums):
res = [0] * len(nums)
stack = [] #indexes from hottest to coldest
for i in range(len(nums) - 1, -1, -1):
while stack and nums[i] >= nums[stack[-1]]:
stack.pop() #remove lower and not soonest
if stack:
res[i] = stack[-1] - i
stack.append(i)
return res
结论:
在上述所有解决方案中,条件class Solution4:
def dailyTemperatures(self, nums: 'List[int]') -> 'List[int]':
"""
Runtime: 300 ms, faster than 74.12%
Memory Usage: 16.6 MB, less than 9.45%
"""
res = [0] * len(nums)
stack = []
for i in range(len(nums)):
while stack and nums[i] > nums[stack[-1]]: #find the higher
cur = stack.pop()
res[cur] = i - cur
stack.append(i)
return res
未得到利用。
这种情况是什么意思?
答案 0 :(得分:2)
您可以使用enumerate()和index()函数在列表理解中做到这一点:
[ [t<n for n in T[i:]+[t+1]].index(True)%(len(T)-i) for i,t in enumerate(T)]
# [1, 1, 4, 2, 1, 1, 0, 0]
如果要考虑性能,那么程序方法将运行得更快:
def dailyTemps(T):
result = [0]*len(T)
seeking = []
prevTemp = 0
for i,(t0,t1) in enumerate(zip(T,T[1:])):
while seeking and prevTemp < t0:
ip = seeking.pop(-1)
result[ip] = i - ip
if seeking: prevTemp = T[seeking[-1]]
if t0 >= t1:
seeking.append(i)
prevTemp = t0
else:
result[i] = 1
return result
答案 1 :(得分:1)
条件len(nums) < 30000
用于告诉您数据规模。当面对不同的数据规模时,您可能会使用不同的设计策略。
例如if len(nums) < 30
,蛮力可能是最好的解决方案,没有多余的空间且不够快。
您会在Leetcode中发现许多问题,这些问题也会为您提供此信息。而且您不会在代码中使用它,但会在想法中使用它。