1944. 队列中可以看到的人数

有 n 个人排成一个队列,从左到右 编号为 0 到 n - 1 。给你以一个整数数组 heights ,每个整数 互不相同,heights[i] 表示第 i 个人的高度。

一个人能 看到 他右边另一个人的条件是这两人之间的所有人都比他们两人 矮 。更正式的,第 i 个人能看到第 j 个人的条件是 i < j 且 min(heights[i], heights[j]) > max(heights[i+1], heights[i+2], ..., heights[j-1]) 。

请你返回一个长度为 n 的数组 answer ,其中 answer[i] 是第 i 个人在他右侧队列中能 看到 的 人数

输入:heights = [10,6,8,5,11,9]
输出:[3,1,2,1,1,0]
解释:
第 0 个人能看到编号为 1 ,2 和 4 的人。
第 1 个人能看到编号为 2 的人。
第 2 个人能看到编号为 3 和 4 的人。
第 3 个人能看到编号为 4 的人。
第 4 个人能看到编号为 5 的人。
第 5 个人谁也看不到因为他右边没人。

示例 2:

输入:heights = [5,1,2,3,10]
输出:[4,1,1,1,0]

python代码:

from typing import List


def can_see_persons(heights: List[int]) -> List[int]:
n = len(heights)
stack = []
ans = [0] * n

for i in range(n):
while stack and heights[i] > heights[stack[-1]]:
ans[stack.pop()] += 1
if stack:
ans[stack[-1]] += 1
stack.append(i)

return ans
heights = [10, 6, 8, 5, 11, 9]
print("输入:",heights)
print("输出:",can_see_persons(heights)) # [3, 1, 2, 1, 1, 0]

heights = [5, 1, 2, 3, 10]
print("输入:",heights)
print("输出:",can_see_persons(heights)) # [4, 1, 1, 1, 0]

截图:

 

算法说明:

该算法利用了单调栈的思想,其主要思路如下:

1. 维护一个单调不升的栈,栈中存放的是队列中的索引。

2. 遍历整个队列,对于每个人,如果他的身高大于栈顶元素所对应的身高,则栈顶元素所对应的人可以被当前人看到。因此,将栈顶元素弹出,并将答案数组中对应的元素加 1,直到栈为空或者栈顶元素所对应的身高大于当前人的身高。

3. 此时,当前人可以看到栈顶元素所对应的人和栈顶元素下面的人,因此将栈顶元素所对应的答案数组中的元素加 1。

4. 最后,将当前人的索引压入栈中。

5. 遍历完整个队列后,答案数组中存放的就是每个人在他右侧队列中能看到的人数。

该算法的时间复杂度为 $O(n)$,其中 $n$ 是队列的长度。因为每个人只会被压入栈中一次,也只会被弹出栈中一次,所以总共需要进行 $2n$ 次栈操作,每次操作的时间复杂度为 $O(1)$。因此,该算法的时间复杂度为 $O(n)$。

该算法的空间复杂度为 $O(n)$,因为需要维护一个长度为 $n$ 的栈和一个长度为 $n$ 的答案数组。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牛马程序员24

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值