[LeetCode 周賽187] 3. 絕對差不超過限制的最長連續子數組(暴力、優先隊列、常規解法)

1. 題目來源

鏈接:5402. 絕對差不超過限制的最長連續子數組

2. 題目說明

在這裏插入圖片描述
在這裏插入圖片描述

3. 題目解析

方法一:暴力投機+常規解法

很暴力的一個暴力解法,加上一個特判就過了,若數組的最大項減去最小項還小於等於 limit 的話,說明應該返回整個數組長度。這個可有效避免重複項…但這個屬實有點投機了,不推薦,但是真香 😃。

參見代碼如下:

// 執行用時 :124 ms, 在所有 C++ 提交中擊敗了100.00%的用戶
// 內存消耗 :30.3 MB, 在所有 C++ 提交中擊敗了100.00%的用戶

class Solution {
public:
    int longestSubarray(vector<int>& nums, int limit) {
        int res = 0, c = nums[0], d = nums[0];
        for (auto e : nums) c = max(c, e), d = min(d, e);
        if (abs(c - d) <= limit) return nums.size();
        
        for (int i = 0; i < nums.size(); ++i) {
            int mx = nums[i], mi = nums[i], j = i;
            for (j; j < nums.size(); ++j) {
                mx = max(mx, nums[j]);
                mi = min(mi, nums[j]);
                if (abs(mx - mi) > limit) break;
            }
            res = max(res, j - i);
        }
        return res;
    }
};

方法二:優先隊列+雙指針+巧妙解法

這道題符合雙指針思想,即固定 left 使 right 在條件下不斷向右移動,移動到 n 或者未在條件內就跳出循環。採用兩個優先隊列來求出區間的最大、最小值。這個的時間複雜度爲 O(nlogn)O(nlogn),並且採用優先隊列求最大值就正常數據輸入即可,求最小值時可以採用給數據乘負號的形式輸入,輸出時再乘負號即可。在此 make_pair 是一個函數,無法使用 typedef,就使用簡單的宏替換即可,相當於字符串替換。但還是儘量少用宏定義吧。

不過這執行用時真的離譜了點…確實最後一個 case 很頂啊,不過這個解法確實能有效通過最後一個用例。

參見代碼如下:

// 執行用時 :468 ms, 在所有 C++ 提交中擊敗了100.00%的用戶
// 內存消耗 :34.7 MB, 在所有 C++ 提交中擊敗了100.00%的用戶

typedef pair<int, int> PII;
#define MP(x, y) make_pair(x, y)
class Solution {
public:
    int longestSubarray(vector<int>& nums, int limit) {
        int ans = 0, n = nums.size();
        priority_queue<PII> mxq, miq;
        for (int i = 0, r = 0; i < n; ++i) {
            while (!mxq.empty() and mxq.top().second < i) mxq.pop();
            while (!miq.empty() and miq.top().second < i) miq.pop();
            int mx = 0, mi = 1e9 + 1;
            if (!mxq.empty()) mx = mxq.top().first;
            if (!mxq.empty()) mi = -miq.top().first;
            while (r < n and max(mx, nums[r]) - min(mi, nums[r]) <= limit) {
                mxq.push(MP(nums[r], r));
                miq.push(MP(-nums[r], r));
                mx = max(mx, nums[r]);
                mi = min(mi, nums[r]);
                ++r;
            }
            ans = max(ans, r - i);
        }
        return ans;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章