【力扣roadmap】1438. 绝对差不超过限制的最长连续子数组

25 阅读1分钟

题目描述

  • 竞赛积分1672
  • 题号1438

image.png

思路

维护滑动的窗口的同时,我们需要维护窗口内部的最大值和最小值。我们可以直接借助数据结构帮我们办到这个事情。 对于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