原题地址(中等)
方法1—暴力(时间超限)
思路
首先想到的就是暴力,双重循环来尝试所有的可能。不过时间超限了。
代码
class Solution {public:int longestSubarray(vector<int>& nums, int limit) {int n = nums.size(), ans = 0;if(!n) return 0;for(int i = 0; i < n; i++) {int maxVal = nums[i], minVal = nums[i];for(int j = i; j < n; j++) {if(nums[j] > maxVal) maxVal = nums[j];if(nums[j] < minVal) minVal = nums[j];if(maxVal - minVal <= limit) ans = max(ans, j - i + 1);}}return ans;}};
时空复杂度
方法2—滑动窗口+有序集合
这道题其实是考察了对语言各种模板函数的运用程度。
c++的话用multiset或者map就很好做了。
思路
这个是看的官解,主要是利用了c++自带的红黑树。然后使用滑动窗口枚举每一个位置作为右端点,找到其对应的最靠左的左端点,满足区间中最大值与最小值的差不超过limit。
也可以用 map<int, int> ,map会对数据自动排序,内部也是红黑树。
代码
multiset
class Solution {public:int longestSubarray(vector<int>& nums, int limit) {multiset<int> ms;int n = nums.size(), left = 0, right = 0, ans = 0;while(right < n) {ms.insert(nums[right]);while(*ms.rbegin() - *ms.begin() > limit)ms.erase(ms.find(nums[left++]));ans = max(ans, right - left + 1);right++;}return ans;}};
map
class Solution {public:int longestSubarray(vector<int>& nums, int limit) {map<int, int> m;int n = nums.size(), left = 0, right = 0, ans = 0;while(right < n) {m[nums[right]]++;while(m.rbegin()->first - m.begin()->first > limit){m[nums[left++]]--;if(m[nums[left-1]] == 0) m.erase(nums[left-1]);}ans = max(ans, right - left + 1);right++;}return ans;}};
时空复杂度
时间 空间
方法3—滑动窗口+队列
思路
可用两个双端队列来存储最大最小值,不断更新,这样寻找子串的最大最小值直接取两个队列的头元素相减即可。
见官解方法2
代码
class Solution {public:int longestSubarray(vector<int>& nums, int limit) {deque<int> queMax, queMin;int n = nums.size(), left = 0, right = 0, ans = 0;while(right < n) {// 保证queMax的元素都比nums[right]大while(!queMax.empty() && queMax.back() < nums[right])queMax.pop_back();// 保证queMin的元素都比nums[right]小while(!queMin.empty() && queMin.back() > nums[right])queMin.pop_back();queMax.push_back(nums[right]);queMin.push_back(nums[right]);while(!queMax.empty() && !queMin.empty() && queMax.front() - queMin.front() > limit) {if(nums[left] == queMax.front()) queMax.pop_front();if(nums[left] == queMin.front()) queMin.pop_front();left++;}ans = max(ans, right - left + 1);right++;}return ans;}};
时空复杂度
均为
