题目描述
竞赛积分1672题号1438
思路
维护滑动的窗口的同时,我们需要维护窗口内部的最大值和最小值。我们可以直接借助数据结构帮我们办到这个事情。 对于c++来说是multiset,这是一种允许重复元素的set。以logn的复杂度进行查询插入删除操作。对于python来说,我们可以借助SortedList。
枚举r右端点,每次枚举默认将其纳入窗口,并取出当前窗口的最大最小值进行检查。如果不合法,那么开始进行窗口调整使之合法。调整方法,就是找到左端元素将其删除(logn的复杂度),并刷新最大最小值再次检查窗口是否合法。
代码
class Solution {
public:
int longestSubarray(vector<int>& nums, int limit) {
// 使用multiset维护最大值和最小值
int l = 0 ;
int r = 0 ;
int n = nums.size() ;
multiset<int> ms ;
int ans = 0 ;
for (r = 0 ; r < n ; r ++) {
ms.insert(nums[r]) ;
int mn = *ms.begin() ;
int mx = *ms.rbegin() ;
while (l < r && mx - mn > limit) {
auto c = ms.find(nums[l]) ;
ms.erase(c) ;
l ++ ;
mx = *ms.begin();
mn = *ms.rbegin() ;
}
ans = max(ans , r - l + 1) ;
}
return ans ;
}
};
class Solution:
def longestSubarray(self, nums: List[int], limit: int) -> int:
l = 0
ans = 0
n = len(nums)
sl = SortedList()
for r in range(n):
sl.add(nums[r])
mn = sl[0]
mx = sl[-1]
while l < r and mx - mn > limit:
idx = sl.index(nums[l])
sl.pop(idx)
l += 1
mn = sl[0]
mx = sl[-1]
ans = max(ans, r - l + 1)
return ans