2024-09-13 20:08阅读: 5评论: 0推荐: 0

滑动窗口+单调队列

题目:

2398. 预算内的最多机器人数目

答案:

copy
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
# from typing import List # from collections import deque class Solution: def maximumRobots(self, chargeTimes: List[int], runningCosts: List[int], budget: int) -> int: res, n, runningCostSum = 0, len(chargeTimes), 0 q, i = deque(), 0 for j in range(n): runningCostSum += runningCosts[j] # 维护q,保证它递减 while q and chargeTimes[q[-1]] <= chargeTimes[j]: q.pop() q.append(j) # i==j还进入循环,说明这里一个都不行,i会变成i+1退出循环,cost都会被清空 while i <= j and (j - i + 1) * runningCostSum + chargeTimes[q[0]] > budget: # 如果i是目前最大的,只需移除它即可,有j作为保障 if q and q[0] == i: q.popleft() runningCostSum -= runningCosts[i] i += 1 res = max(res, j - i + 1) return res ''' 滑动窗口、双指针 关键是用q来维持chargeTime最大值 每次j向后移,都会将j加入,同时清除j前面比j小的,这就保证了队列里的charge是递减的, 当某次i需要向后移,且i就是最大charge时,直接删掉这一个q就行,后面一定有第二大或者最后加的j '''

总结:

  1. 滑动窗口就是这样一个数组,j逐个往后增,每轮对i按要求进行左右移动,不断重复此过程
  2. 滑动窗口里的最大最小值,关键是用单调队列,j又一定会添加进去,保证无论i怎么变,都能直接找到下一个最值

补充:滑动窗口模板

在LeetCode看到的一个评论

copy
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
//外层循环扩展右边界,内层循环扩展左边界 for (int l = 0, r = 0 ; r < n ; r++) { //当前考虑的元素 while (l <= r && check()) {//区间[left,right]不符合题意 //扩展左边界 } //区间[left,right]符合题意,统计相关信息 }

本文作者:faf4r

本文链接:https://www.cnblogs.com/faf4r/p/18412804

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   faf4r  阅读(5)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起