0% completed
Problem Statement
You are given a 0-indexed array of integers called nums
. A subarray of num
is called continuous if the following condition is met:
- consider i, i + 1, ..., j be the indices in the subarray. Then, for each pair of indices i <= i1, i2 <= j, 0 <= |nums[i1] - nums[i2]| <= 2.
Return the total number of continuous subarrays within nums
.
A subarray is defined as any contiguous, non-empty sequence of elements within an array.
Examples
Example 1:
- Input: nums =
[1, 2, 2, 13, 1]
- Expected Output:
8
- Justification: The continuous subarrays are [1], [2], [2], [13], [1], [1, 2], [2, 2], and [1, 2, 2].
Example 2:
- Input: nums =
[3, 3, 4, 2]
- Expected Output:
10
- Justification: The continuous subarrays are [3], [3], [4], [2], [3, 3], [3, 4], [4, 2], [3, 3, 4], [3, 4, 2], and [3, 3, 4, 2].
Example 3:
- Input: nums =
[5, 17, 35, 26, 5]
- Expected Output:
5
- Justification: The continuous subarrays are [5], [17], [35], [26], and [5].
Constraints:
- 1 <= nums.length <= 10<sup>5</sup>
- 1 <= nums[i] <= 10<sup>9</sup>
Solution
This problem is similar to the "Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit" problem, but with a twist. In this case, the limit is fixed at 2, meaning that we must find all subarrays where the maximum difference between any two elements does not exceed 2. The goal is to count the total number of such continuous subarrays within the given array.
To solve this problem, we use a sliding window approach combined with two deques (double-ended queues) to efficiently track the minimum and maximum values within the current subarray. The deques allow us to maintain the order of elements in a way that makes it easy to adjust the window size dynamically by moving the left pointer whenever the difference between the maximum and minimum values exceeds 2. By counting all valid subarrays ending at each position, we can calculate the total number of continuous subarrays that satisfy the condition.
Step-by-Step Algorithm
-
Initialize Deques and Pointers:
- Start by creating two empty deques,
maxQ
andminQ
. These will help us keep track of the maximum and minimum values within the current subarray. - Initialize two pointers:
left
to 0 (start of the subarray) andright
to 0 (end of the subarray). - Also, initialize
ans
to 0, which will store the total count of continuous subarrays, andn
to the length of the input arraynums
.
- Start by creating two empty deques,
-
Iterate Over the Array:
- Begin a loop with the
right
pointer moving from the start to the end of the array. - For each element at position
right
, perform the following steps:
- Begin a loop with the
-
Maintain Decreasing Order in
maxQ
:- While
maxQ
is not empty and the last element inmaxQ
is less than the current element (nums[right]
), remove elements from the back ofmaxQ
. - This step ensures that
maxQ
always contains elements in decreasing order from front to back, with the maximum value at the front.
- While
-
Maintain Increasing Order in
minQ
:- Similarly, while
minQ
is not empty and the last element inminQ
is greater than the current element (nums[right]
), remove elements from the back ofminQ
. - This step ensures that
minQ
always contains elements in increasing order from front to back, with the minimum value at the front.
- Similarly, while
-
Add Current Element to Deques:
- Add the current element (
nums[right]
) to bothmaxQ
andminQ
.
- Add the current element (
-
Adjust the
left
Pointer:- While the difference between the maximum value (
maxQ.peekFirst()
) and the minimum value (minQ.peekFirst()
) is greater than 2:- If the element at the
left
pointer is equal to the first element inmaxQ
, remove it frommaxQ
. - If the element at the
left
pointer is equal to the first element inminQ
, remove it fromminQ
. - Move the
left
pointer to the right by incrementingleft
. - This step ensures that the subarray always satisfies the condition
max - min <= 2
.
- If the element at the
- While the difference between the maximum value (
-
Count Valid Subarrays:
- Add the number of valid subarrays ending at the
right
pointer toans
. The number of such subarrays isright - left + 1
.
- Add the number of valid subarrays ending at the
-
Continue Until End of Array:
- Continue this process until the
right
pointer has iterated through the entire array.
- Continue this process until the
-
Return the Result:
- Finally, return
ans
, which contains the total number of valid continuous subarrays.
- Finally, return
Algorithm Walkthrough
Let's consider the Input: nums = [1, 2, 2, 13, 1]
-
Initialization:
left = 0
,right = 0
,ans = 0
.maxQ
=[]
,minQ
=[]
.
-
Iteration 1 (
right = 0
):- Current element:
nums[0] = 1
. maxQ
andminQ
are empty. So, add1
to bothmaxQ
andminQ
.- Since
maxQ.peekFirst() - minQ.peekFirst() = 1 - 1 = 0
(which is ≤ 2), the subarray[1]
is valid. - Valid subarrays count:
1
(for the subarray[1]
). - Update ans = ans + right - left + 1 =
0 + 0 + 0 + 1 = 1
. maxQ
=[1]
,minQ
=[1]
.
- Current element:
-
Iteration 2 (
right = 1
):- Current element:
nums[1] = 2
. - Maintain
maxQ
: Remove1
frommaxQ
(since1 < 2
), then add2
tomaxQ
. - Maintain
minQ
: Add2
tominQ
. - Since
maxQ.peekFirst() - minQ.peekFirst() = 2 - 1 = 1
(which is ≤ 2), the subarrays[2]
and[1, 2]
are valid. - Valid subarrays count:
right - left + 1 = 1 - 0 + 1 = 2
(for the subarrays[2]
and[1, 2]
). - Update
ans = 3
. maxQ
=[2]
,minQ
=[1, 2]
.
- Current element:
-
Iteration 3 (
right = 2
):- Current element:
nums[2] = 2
. - Maintain
maxQ
: Add2
tomaxQ
. - Maintain
minQ
: Add2
tominQ
. - Since
maxQ.peekFirst() - minQ.peekFirst() = 2 - 1 = 1
(which is ≤ 2), the subarrays[2]
,[2, 2]
, and[1, 2, 2]
are valid. - Valid subarrays count:
right - left + 1 = 2 - 0 + 1 = 3
(for the subarrays[2]
,[2, 2]
, and[1, 2, 2]
). - Update
ans = 6
. maxQ
=[2, 2]
,minQ
=[1, 2, 2]
.
- Current element:
-
Iteration 4 (
right = 3
):- Current element:
nums[3] = 13
. - Maintain
maxQ
: Remove2
and2
frommaxQ
(since2 < 13
), then add13
tomaxQ
. - Maintain
minQ
: Add13
tominQ
. - Since
maxQ.peekFirst() - minQ.peekFirst() = 13 - 1 = 12
(which is > 2), we adjust theleft
pointer:- Move
left
to1
, remove1
fromminQ
. - Since
13 - 2 = 11
(which is still > 2), moveleft
to2
, remove2
fromminQ
. - Since
13 - 2 = 11
(which is still > 2), moveleft
to3
, remove2
fromminQ
.
- Move
- Now, with
left = 3
,maxQ.peekFirst() - minQ.peekFirst() = 13 - 13 = 0
(which is ≤ 2), the subarray[13]
is valid. - Valid subarrays count:
right - left + 1 = 3 - 3 + 1 = 1
(for the subarray[13]
). - Update
ans = 7
. maxQ
=[13]
,minQ
=[13]
.
- Current element:
-
Iteration 5 (
right = 4
):- Current element:
nums[4] = 1
. - Maintain
maxQ
: Add1
tomaxQ
. - Maintain
minQ
: Remove13
fromminQ
, add1
tominQ
. - Since
maxQ.peekFirst() - minQ.peekFirst() = 13 - 1 = 12
(which is > 2), adjust theleft
pointer:- Move
left
to4
, remove13
frommaxQ
.
- Move
- Now, with
left = 4
,maxQ.peekFirst() - minQ.peekFirst() = 1 - 1 = 0
(which is ≤ 2), the subarray[1]
is valid. - Valid subarrays count:
right - left + 1 = 4 - 4 + 1 = 1
(for the subarray[1]
). - Update
ans = 8
. maxQ
=[1]
,minQ
=[1]
.
- Current element:
-
End of Loop:
- The loop ends with
right
reaching the end of the array. - The final answer is
8
, representing the total number of valid continuous subarrays.
- The loop ends with
Code
Complexity Analysis
Time Complexity
- The time complexity of this algorithm is O(n), where
n
is the length of the input arraynums
. - The
right
pointer traverses each element of the array exactly once. - The
left
pointer may also traverse each element once, but since every element is added and removed from the deque at most once, the operations inside the loops (adding and removing elements from the deque) are amortized O(1) operations. - Therefore, the overall time complexity remains O(n).
Space Complexity
- The space complexity of the algorithm is O(n) because we use two deques (
maxQ
andminQ
) to store elements from the array. In the worst case, all elements could be stored in these deques, leading to a space complexity proportional to the size of the input array.
.....
.....
.....
On this page
Problem Statement
Examples
Solution
Step-by-Step Algorithm
Algorithm Walkthrough
Code
Complexity Analysis
Time Complexity
Space Complexity