The longest continuous sub-array whose absolute difference does not exceed the limit-two methods of sliding window

The longest continuous sub-array whose absolute difference does not exceed the limit, title address

1. Ideas

  1. Use a sliding window to keep the eligible sub-arrays and record the longest length
  2. Two data are required: the maximum value and the minimum value in the sliding window
  3. Need to record the data that slides into the window, delete the data that slides out, and update the maximum and minimum values

Two, map + sliding window

We can use map to record, because a red-black tree (a non-strictly balanced binary tree) is built inside the map. This tree has the function of automatically sorting data, so all the data in the map has Orderly, all can find the maximum and minimum values ​​in the sliding array to update.

class Solution {
    
    
public:
int longestSubarray(vector<int>& nums, int limit)
{
    
    
	map < int, int > m;
	int ans = 0;
	int j = 0;
	for (int i = 0; i < nums.size(); i++)
	{
    
    
		m[nums[i]]++;
		while (m.rbegin()->first - m.begin()->first > limit)
		{
    
    
			m[nums[j]]--;//j位置的数划出
			if (m[nums[j]] == 0)//数量为0直接删除该键值对
				m.erase(nums[j]);
			j++;
		}
		ans = max(ans, i - j + 1);//更新
	}
	return ans;
}
};

Three, deque (queue)

The two monotonic queues maintain the maximum value, the minimum value, and the head of the queue respectively represent the minimum and maximum values ​​in the sliding window. When abs(q1.front()-q2.front())> limit, the window shrinks, j++.

In this case, the complexity is only O(n)

class Solution {
    
    
public:
	int longestSubarray(vector<int>& nums, int limit)
	{
    
    
		int ans = 0;
		deque<int> q1, q2;   //双端队列来维护单调队列
		for (int i = 0, j = 0; i < nums.size(); i++)
		{
    
    //队头分别表示滑动窗口中的最小值、最大值。
			while (!q1.empty() && q1.back() > nums[i]) q1.pop_back();//维护单调增队列
			q1.push_back(nums[i]);
			while (!q2.empty() && q2.back() < nums[i]) q2.pop_back();//维护单调减队列
			q2.push_back(nums[i]);
			//检测当前窗口是否满足条件
			while (!q1.empty() && !q2.empty() && q2.front() - q1.front() > limit) 
			{
    
    
				if (nums[j] == q1.front()) q1.pop_front();      //从队头出队
				if (nums[j] == q2.front()) q2.pop_front();      //从队头出队
				j++;
			}
			ans = max(ans, i - j + 1);
		}
        return ans;
	}
};

Guess you like

Origin blog.csdn.net/weixin_45605341/article/details/108679244