假设我们有一个称为nums的整数数组和一个整数限制,我们必须找到最长的非空子数组的大小,以使该子数组的任何两项之间的绝对差小于或等于给定的限制。
因此,如果输入类似于nums = [8,2,4,7],limit = 4,则输出将为2,这是因为-
[8]如此| 8-8 | = 0 <= 4。
[8,2]如此| 8-2 | = 6> 4。
[8,2,4]如此| 8-2 | = 6> 4。
[8,2,4,7]如此| 8-2 | = 6> 4。
[2]如此| 2-2 | = 0 <= 4。
[2,4]如此| 2-4 | = 2 <= 4。
[2,4,7]如此| 2-7 | = 5> 4。
[4]如此| 4-4 | = 0 <= 4。
[4,7]如此| 4-7 | = 3 <= 4。
[7]如此| 7-7 | = 0 <= 4。
最后,最长子数组的大小为2。
为了解决这个问题,我们将遵循以下步骤-
ret:= 0,i:= 0,j:= 0
定义一个双端队列maxD和另一个双端队列minD
n:= nums的大小
对于初始化i:= 0,当i <n时,更新(将i增加1),执行-
如果nums [j]与maxD的第一个元素相同,则-
如果nums [j]与minD的第一个元素相同,则-
(将j增加1)
从maxD删除前元素
从minD删除前元素
从minD删除最后一个元素
从maxD删除最后一个元素
while(不是maxD为空,并且maxD <nums [i]的最后一个元素),执行-
而(非minD为空,minD的最后一个元素> nums [i]),则执行-
在maxD的末尾插入nums [i]
在minD的末尾插入nums [i]
while(maxD的第一个元素-minD的第一个元素)> k,执行-
ret:= ret的最大值和(i-j + 1)
返回ret
让我们看下面的实现以更好地理解-
#include <bits/stdc++.h> using namespace std; class Solution { public: int longestSubarray(vector<int>& nums, int k) { int ret = 0; int i = 0; int j = 0; deque<int> maxD; deque<int> minD; int n = nums.size(); for (int i = 0; i < n; i++) { while (!maxD.empty() && maxD.back() < nums[i]) maxD.pop_back(); while (!minD.empty() && minD.back() > nums[i]) minD.pop_back(); maxD.push_back(nums[i]); minD.push_back(nums[i]); while (maxD.front() - minD.front() > k) { if (nums[j] == maxD.front()) maxD.pop_front(); if (nums[j] == minD.front()) minD.pop_front(); j++; } ret = max(ret, i - j + 1); } return ret; } }; main(){ Solution ob; vector<int> v = {7,8,2,4}; cout << (ob.longestSubarray(v, 4)); }
{7,8,2,4}, 4
输出结果
2