题目描述
nums2中元素都不同,num1是nums2的一个子集。
需要找出nums2中每个元素下一个更大的元素,在映射回nums1中?
基本分析
- 向右找最近的更大的值,维护递增栈还是递减的栈,是严格的吗?需要维护非严格递减的栈,例如43342,33都会入栈。
- 找到的逻辑是什么?当遇到一个d > st[-1].值 时候,对st[-1]来说d就是他的最近的更大的值,弹出+记录后,继续看st[-1]是不是类似。什么时候终止while?栈空了或者不满足st[-1].值 < d, 例如334 或者4334分别对应4的时候。
- 这种找法所有的值都能赋上吗,或者栈中剩下什么?栈中剩下一个非严格单调减的索引序列,序列的右边没有更大的元素了,所以序列里面的索引应该对应一个设置好的初值(-1或者n)
- 为什么用哈希表维护不是数组?数组维护的话是索引,值和索引还是不一样的。
代码
| class Solution: |
| def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]: |
| |
| m, n = len(nums1), len(nums2) |
| # nums2中下一个最大元素的索引 |
| right = dict() |
| st = [] |
| # st中放索引还是值? |
| for i, d in enumerate(nums2): |
| while st and d > nums2[st[-1]]: |
| top = st.pop() |
| right[nums2[top]] = d |
| st.append(i) |
| |
| for idx in st: |
| right[nums2[idx]] = -1 |
| |
| ans = [] |
| for d in nums1: |
| ans.append(right[d]) |
| |
| return ans |
总结
- 找右边更大的,用单调递减栈,可以存在=的情况
- 维护信息的时候是弹出的时候,i或者d就是需要的信息
- 没有弹出的元素没有信息,需要初值或者后续维护
基本分析
- 右到左需要维护的是什么?严格单调递减的栈
- 可以得到right的逻辑?倒序遍历,对i=n-1时候,栈是空,直接追加。其他时候,只有st[-1]严格>nums2[i]的时候,i才认老大,否则就一直踢馆,最后的结果是栈空(i对应的结果是-1),或者找到老大(st[-1])
- 这种情况遍历过以后还需要维护结果吗?对找不到老大的时候,认了-1了,不用再管了
代码
| class Solution: |
| def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]: |
| right = dict() |
| |
| n = len(nums2) |
| st = [] |
| |
| for i in range(n-1, -1, -1): |
| # i一直在栈里挖,想找到比他大的值 |
| # 不满足的时候就一直弹出来(栈里面的值都需要是自己的老大) |
| while st and nums2[i] >= nums2[st[-1]]: |
| st.pop() |
| if st: |
| right[nums2[i]] = nums2[st[-1]] |
| else: |
| right[nums2[i]] = -1 |
| st.append(i) |
| |
| ans = [] |
| for d in nums1: |
| ans.append(right[d]) |
| |
| return ans |
总结
- 1是弹出的时候pop出的是索引,i是他找到的信息,可能多个弹出的结果都是i,这样一个while中可能赋值多次;2是 i一直在st中挖结果,直到挖出或者挖空以后,在while外面赋值;
- 前者是d > 栈顶值时候才弹栈,弹出的是严格< d的值;后者是 d >= 栈顶值的时候就弹栈。
- 为啥设置成这样?1弹出的时候表示i就是top要找的信息,所以对334情况,栈中可以有值相等的(1,2);对于2的情况,是i要去栈中找结果,栈就要严格递减(否则可能认错大哥,3认了右边的3)。
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现