defnext_greater_element(nums): n = len(nums) result = [-1] * n # 默认值为-1,表示没有更大的元素 stack = [] # 存储元素的索引 for i inrange(n): # 当前元素大于栈顶元素时,更新结果 while stack and nums[i] > nums[stack[-1]]: result[stack[-1]] = nums[i] # 当前元素是栈顶元素的下一个更大元素 stack.pop() stack.append(i) # 将当前元素索引入栈 return result
寻找下一个更小元素模板(单调递增栈)
1 2 3 4 5 6 7 8 9 10 11 12 13
defnext_smaller_element(nums): n = len(nums) result = [-1] * n # 默认值为-1,表示没有更小的元素 stack = [] # 存储元素的索引 for i inrange(n): # 当前元素小于栈顶元素时,更新结果 while stack and nums[i] < nums[stack[-1]]: result[stack[-1]] = nums[i] # 当前元素是栈顶元素的下一个更小元素 stack.pop() stack.append(i) # 将当前元素索引入栈 return result
寻找前一个更大元素模板(单调递减栈)
1 2 3 4 5 6 7 8 9 10 11 12 13
defprev_greater_element(nums): n = len(nums) result = [-1] * n # 默认值为-1,表示没有更大的元素 stack = [] # 存储元素的索引 for i inrange(n-1, -1, -1): # 当前元素大于栈顶元素时,更新结果 while stack and nums[i] > nums[stack[-1]]: result[stack[-1]] = nums[i] # 当前元素是栈顶元素的前一个更大元素 stack.pop() stack.append(i) # 将当前元素索引入栈 return result
寻找前一个更小元素模板(单调递增栈)
1 2 3 4 5 6 7 8 9 10 11 12 13
defprev_smaller_element(nums): n = len(nums) result = [-1] * n # 默认值为-1,表示没有更小的元素 stack = [] # 存储元素的索引 for i inrange(n-1, -1, -1): # 当前元素小于栈顶元素时,更新结果 while stack and nums[i] < nums[stack[-1]]: result[stack[-1]] = nums[i] # 当前元素是栈顶元素的前一个更小元素 stack.pop() stack.append(i) # 将当前元素索引入栈 return result
defnextGreaterElement(nums1, nums2): next_greater = {} stack = [] # 构建nums2中每个元素的下一个更大元素映射 for num in nums2: while stack and stack[-1] < num: next_greater[stack[-1]] = num stack.pop() stack.append(num) # 从映射中获取nums1中每个元素的答案 result = [] for num in nums1: result.append(next_greater.get(num, -1)) return result
力扣 84:柱状图中最大的矩形
问题描述:给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1。求在该柱状图中,能够勾勒出来的矩形的最大面积。
deftrap(height): n = len(height) result = 0 stack = [] for i inrange(n): while stack and height[i] > height[stack[-1]]: top = stack.pop() ifnot stack: break # 计算宽度和高度 width = i - stack[-1] - 1 bounded_height = min(height[i], height[stack[-1]]) - height[top] # 累加接水量 result += width * bounded_height stack.append(i) return result
力扣 739:每日温度
问题描述:给定一个整数数组 temperatures,表示每天的温度,返回一个数组 answer,其中 answer[i] 是指在第 i 天之后,才会有更高温度的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。
解决方案:
1 2 3 4 5 6 7 8 9 10 11 12
defdailyTemperatures(temperatures): n = len(temperatures) answer = [0] * n stack = [] # 存储索引 for i inrange(n): while stack and temperatures[i] > temperatures[stack[-1]]: prev_idx = stack.pop() answer[prev_idx] = i - prev_idx stack.append(i) return answer
deffind_both_adjacent_greater(nums): n = len(nums) next_greater = [-1] * n prev_greater = [-1] * n # 找下一个更大元素 stack = [] for i inrange(n): while stack and nums[i] > nums[stack[-1]]: next_greater[stack[-1]] = nums[i] stack.pop() stack.append(i) # 找前一个更大元素 stack = [] for i inrange(n-1, -1, -1): while stack and nums[i] > nums[stack[-1]]: prev_greater[stack[-1]] = nums[i] stack.pop() stack.append(i) return next_greater, prev_greater
处理循环数组:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
defnext_greater_element_circular(nums): n = len(nums) result = [-1] * n stack = [] # 遍历两次数组 for i inrange(n * 2): idx = i % n while stack and nums[idx] > nums[stack[-1]]: result[stack[-1]] = nums[idx] stack.pop() # 只在第一次遍历时入栈 if i < n: stack.append(idx) return result
defmax_value_in_sliding_window(nums, k): n = len(nums) result = [] # 使用双端队列实现单调递减队列 deque = [] for i inrange(n): # 保持队列头部是当前窗口内的元素 while deque and deque[0] < i - k + 1: deque.pop(0) # 维护单调递减性质 while deque and nums[i] > nums[deque[-1]]: deque.pop() deque.append(i) # 当窗口形成后,记录结果 if i >= k - 1: result.append(nums[deque[0]]) return result