Leetcode 1438. 絕對差不超過限制的最長連續子數組 (滑動窗口同時維護最大值以及最小值)

 

這道題目的是典型的滑動窗口問題,需要維護窗口裏面最大值和最小值,要實現這一點,可以利用map(set不行,因爲會有重的,要用

O(nlogn)的實現map

class Solution {
public:
    int longestSubarray(vector<int>& nums, int limit) {
        // 維護滑動窗口裏的最大值以及最小值
        map<int,int> treemap;
        int res = 0;
        for(int i=0,j=0;i<nums.size();i++){
            while(j<nums.size()){
                treemap[nums[j]]++;
                if(treemap.rbegin()->first-treemap.begin()->first<=limit){
                    res = max(res,j-i+1);
                    j++;
                }else{
                    treemap[nums[j]]--;
                    if(treemap[nums[j]]==0) treemap.erase(nums[j]);
                    break;
                }
            }
            treemap[nums[i]]--;
            if(treemap[nums[i]]==0) treemap.erase(nums[i]);
        }
        return res;
    }
};

multiset的解法,multiset的erase方法需要特別注意。 

class Solution {
public:
    int longestSubarray(vector<int>& nums, int limit) {
        // 維護滑動窗口裏的最大值以及最小值
        multiset<int> treemap;
        int res = 0;
        for(int i=0,j=0;i<nums.size();i++){
            while(j<nums.size()){
                treemap.insert(nums[j]);
                if(*treemap.rbegin()-*treemap.begin()<=limit){
                    res = max(res,j-i+1);
                    j++;
                }else{
                    treemap.erase(treemap.find(nums[j]));
                    break;
                }
            }
            treemap.erase(treemap.find(nums[i]));
        }
        return res;
    }
};

接近O(N)的做法,單調雙端隊列,這個做法比較難:

維護一個雙端隊列,使得第一個元素始終爲當前滑動窗口的最大或者最小元素。需要用到單調的思想。

class Solution {
public:
    int longestSubarray(vector<int>& nums, int limit) {
        deque<int> maxDeque;
        deque<int> minDeque;   
        int res= 0; 
        for(int i=0,j=0;j<nums.size();j++){
            while(!maxDeque.empty()&&nums[j]>maxDeque.back()) maxDeque.pop_back();
            while(!minDeque.empty()&&nums[j]<minDeque.back()) minDeque.pop_back();
            maxDeque.push_back(nums[j]);
            minDeque.push_back(nums[j]);
            while(maxDeque.front()-minDeque.front()>limit){
                if(minDeque.front()==nums[i]) minDeque.pop_front();
                if(maxDeque.front()==nums[i]) maxDeque.pop_front();
                i++;
            }
            res = max(res,j-i+1);
        }
        return res;
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章