Talentd
FleetCode
Make and follow sheets.Sign in

Continuous Subarrays solution and explanation

MediumArrayHeap (Priority Queue)Monotonic QueueOrdered Set7 min read58.0% acceptanceUpdated 9 Apr 2026
Continuous Subarrays | Detailed Approaches | Time Complexity | Leetcode 2762 | codestorywithMIKcodestorywithMIK · 52:13 · 11K viewsWatch on YouTube
9 more videos on this problem
  1. Continuous Subarrays | Detailed Approaches | Time Complexity | Leetcode 2762 | codestorywithMIKcodestorywithMIK · 52:13 · 11K views
  2. Continuous Subarrays | Leetcode 2762Techdose · 24:05 · 9K views
  3. 2762. Continuous Subarrays | 5 Approaches | Map | Deque | 2 PointersAryan Mittal · 46:28 · 4K views
  4. Continuous Subarrays | Leetcode 2762 | Sliding Window | Contest 352Tech Courses · 15:23 · 3K views
  5. 3 different Approaches | 2762. Continuous Subarrays | Leetcode Weekly Contest 352codingMohan · 36:10 · 3K views
  6. Most optimal solution | 2762. Continuous Subarrays | leetcode daily challenge | shashcodeShashCode · 30:13 · 2K views
  7. 2762. Continuous Subarrays (Leetcode Medium)Programming Live with Larry · 54:13 · 1K views
  8. 【每日一题】LeetCode 2762. Continuous SubarraysHuifeng Guan · 20:16 · 946 views
  9. LeetCode 2762 Continuous Subarrays | Variable Sliding Window | Asked in Google Amazon Adobe UberCode Harmony · 26:21 · 594 views
  10. leetcode 2762. Continuous Subarrays - two-pointer sliding window methodCode-Yao · 10:59 · 476 views

The problem

You are given a 0-indexed integer array nums. A subarray of nums is called continuous if:

  • Let 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.

A subarray is a contiguous non-empty sequence of elements within an array.

Example 1:

Input: nums = [5,4,2,4]
Output: 8
Explanation: 
Continuous subarray of size 1: [5], [4], [2], [4].
Continuous subarray of size 2: [5,4], [4,2], [2,4].
Continuous subarray of size 3: [4,2,4].
There are no subarrys of size 4.
Total continuous subarrays = 4 + 3 + 1 = 8.
It can be shown that there are no more continuous subarrays.

Example 2:

Input: nums = [1,2,3]
Output: 6
Explanation: 
Continuous subarray of size 1: [1], [2], [3].
Continuous subarray of size 2: [1,2], [2,3].
Continuous subarray of size 3: [1,2,3].
Total continuous subarrays = 3 + 2 + 1 = 6.

Constraints:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 109

Approach overview

Problem Overview: Given an integer array nums, count the number of contiguous subarrays where the difference between the maximum and minimum elements is at most 2. For every subarray you consider, the constraint max(nums[i..j]) - min(nums[i..j]) ≤ 2 must hold.

Approach 1: Brute Force (O(n²) time, O(1) space)

The straightforward solution checks every possible subarray. Start an index i, expand the end index j, and track the current minimum and maximum while iterating. If max - min becomes greater than 2, stop extending that subarray because any longer subarray starting at i will also violate the constraint. Each valid extension contributes one to the answer. This approach is easy to reason about and demonstrates the constraint clearly, but the nested iteration leads to O(n²) time in the worst case.

Approach 2: Sliding Window with Monotonic Queues (O(n) time, O(n) space)

The optimal solution maintains a dynamic window using the sliding window technique. Two pointers left and right represent the current window. The challenge is efficiently tracking the minimum and maximum values as the window grows and shrinks. Use two monotonic queues: one decreasing deque to store candidates for the maximum and one increasing deque for the minimum.

When you expand the window by moving right, push the element into both deques while preserving their monotonic order. The front of each deque always represents the current window's max and min. If max - min > 2, shrink the window by moving left and removing elements from the deque fronts when they leave the window. For every valid position of right, all subarrays ending at right and starting between left and right are valid, contributing right - left + 1 to the count.

This approach processes each element at most twice (once entering the window and once leaving), resulting in O(n) time complexity with O(n) auxiliary space for the deques. It combines ideas from array processing and monotonic data structures to maintain window constraints efficiently.

Recommended for interviews: The sliding window with monotonic queues is the expected solution. Interviewers want to see that you recognize the constraint depends only on the window's min and max, then maintain those values efficiently while adjusting two pointers. Brute force shows you understand the problem definition, but the linear-time window technique demonstrates strong algorithmic optimization skills.

Approach 1: Sliding Window Approach

This approach utilizes a sliding window to find all valid continuous subarrays.

We maintain a window from position 'start' to 'end'. As we iterate over the elements, we adjust the 'start' position to ensure all elements within the window meet the condition 0 <= |nums[i1] - nums[i2]| <= 2. For each position 'end', we extend the window to the right and calculate the number of valid subarrays ending at 'end'.

def continuous_subarrays(nums):
    start = 0
    total = 0
    for end in range(len(nums)):
        while start < end and abs(nums[end] - nums[start]) > 2:
            start += 1
        total += end - start + 1
    return total

# Example usage
print(continuous_subarrays([5, 4, 2, 4]))  # Output: 8

The function continuous_subarrays computes the total number of continuous subarrays by using two pointers, 'start' and 'end'. For each new element at 'end', it checks the subarrays that end in this position and calculates how many of them are valid by adjusting 'start'.

Complexity

Time Complexity: O(n) because each element is processed at most twice, once by 'start' and once by 'end'.

Space Complexity: O(1) since no additional data structures are used besides basic variables.

Try this approach in the editor

Approach 2: Brute Force Approach

A naive solution involves examining all subarrays within the array.

For every possible starting index, calculate every ending index and check if the subarray between these indices forms a continuous subarray. This solution is less efficient but can serve as a baseline check for correctness.

function continuousSubarrays(nums) {
    let total = 0;
    for (let start = 0; start < nums.length; start++) {
        for (let end = start; end < nums.length; end++) {
            let isValid = true;
            for (let i = start; i <= end; i++) {
                for (let j = i + 1; j <= end; j++) {
                    if (Math.abs(nums[i] - nums[j]) > 2) {
                        isValid = false;
                        break;
                    }
                }
                if (!isValid) break;
            }
            if (isValid) total++;
        }
    }
    return total;
}

// Example usage
console.log(continuousSubarrays([5, 4, 2, 4])); // Output: 8

In the function continuousSubarrays, nested loops are used to explore every possible subarray. For each subarray, a check is performed to verify if all elements meet the required continuous condition.

Complexity

Time Complexity: O(n^3) due to triple looping over the array to check all subarrays.

Space Complexity: O(1) as no extra space is used beyond variables.

Try this approach in the editor

Approach 3: Brute Force Approach

In this approach, we iterate over all possible subarrays and check the condition for each subarray. Although simple to implement, it's not efficient for large inputs.

def is_continuous(nums, start, end):
    for i in range(start, end + 1):
        for j in range(i + 1, end + 1):
            if abs(nums[i] - nums[j]) > 2:
                return False
    return True


def count_continuous_subarrays(nums):
    count = 0
    for start in range(len(nums)):
        for end in range(start, len(nums)):
            if is_continuous(nums, start, end):
                count += 1
    return count

nums = [5, 4, 2, 4]
print("Total Continuous Subarrays:", count_continuous_subarrays(nums))
public class ContinuousSubarrays {
    public static boolean isContinuous(int[] nums, int start, int end) {
        for (int i = start; i <= end; i++) {
            for (int j = i + 1; j <= end; j++) {
                if (Math.abs(nums[i] - nums[j]) > 2) return false;
            }
        }
        return true;
    }

    public static int countContinuousSubarrays(int[] nums) {
        int count = 0;
        for (int start = 0; start < nums.length; start++) {
            for (int end = start; end < nums.length; end++) {
                if (isContinuous(nums, start, end)) {
                    count++;
                }
            }
        }
        return count;
    }

    public static void main(String[] args) {
        int[] nums = {5, 4, 2, 4};
        System.out.println("Total Continuous Subarrays: " + countContinuousSubarrays(nums));
    }
}
#include <iostream>
#include <vector>
using namespace std;

bool isContinuous(const vector<int>& nums, int start, int end) {
    for (int i = start; i <= end; ++i) {
        for (int j = i + 1; j <= end; ++j) {
            if (abs(nums[i] - nums[j]) > 2) return false;
        }
    }
    return true;
}

int countContinuousSubarrays(const vector<int>& nums) {
    int count = 0;
    for (int start = 0; start < nums.size(); ++start) {
        for (int end = start; end < nums.size(); ++end) {
            if (isContinuous(nums, start, end)) {
                count++;
            }
        }
    }
    return count;
}

int main() {
    vector<int> nums = {5, 4, 2, 4};
    cout << "Total Continuous Subarrays: " << countContinuousSubarrays(nums) << endl;
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int isContinuous(int* nums, int start, int end) {
    for (int i = start; i <= end; i++) {
        for (int j = i + 1; j <= end; j++) {
            if (abs(nums[i] - nums[j]) > 2) return 0;
        }
    }
    return 1;
}

int countContinuousSubarrays(int* nums, int numsSize) {
    int count = 0;
    for (int start = 0; start < numsSize; start++) {
        for (int end = start; end < numsSize; end++) {
            if (isContinuous(nums, start, end)) {
                count++;
            }
        }
    }
    return count;
}

int main() {
    int nums[] = {5, 4, 2, 4};
    int numsSize = sizeof(nums) / sizeof(nums[0]);
    printf("Total Continuous Subarrays: %d\n", countContinuousSubarrays(nums, numsSize));
    return 0;
}
using System;

public class ContinuousSubarrays {
    public static bool IsContinuous(int[] nums, int start, int end) {
        for (int i = start; i <= end; i++) {
            for (int j = i + 1; j <= end; j++) {
                if (Math.Abs(nums[i] - nums[j]) > 2) return false;
            }
        }
        return true;
    }

    public static int CountContinuousSubarrays(int[] nums) {
        int count = 0;
        for (int start = 0; start < nums.Length; start++) {
            for (int end = start; end < nums.Length; end++) {
                if (IsContinuous(nums, start, end)) {
                    count++;
                }
            }
        }
        return count;
    }

    public static void Main() {
        int[] nums = { 5, 4, 2, 4 };
        Console.WriteLine($"Total Continuous Subarrays: {CountContinuousSubarrays(nums)}");
    }
}

The Python solution checks all existing subarrays for continuity, calculating the total count that meet the condition using a helper function to examine element pairs.

Complexity

Time Complexity: O(n^3), dominated by the nested loop structure and the pair check.
Space Complexity: O(1), minimal additional space.

Try this approach in the editor

Approach 4: Sliding Window Approach

This approach uses a more efficient sliding window technique. You slide over the array with two pointers and dynamically maintain the conditions for a valid subarray. Adjust pointers as needed to expand or contract the window based on the condition.

public class ContinuousSubarrays {
    public static int countContinuousSubarrays(int[] nums) {
        int n = nums.length;
        int left = 0, right = 0, count = 0;
        while (right < n) {
            int minVal = nums[right], maxVal = nums[right];
            for (int i = right; i >= left; i--) {
                maxVal = Math.max(maxVal, nums[i]);
                minVal = Math.min(minVal, nums[i]);
                if (maxVal - minVal <= 2) {
                    count++;
                } else {
                    left = i + 1;
                    break;
                }
            }
            right++;
        }
        return count;
    }

    public static void main(String[] args) {
        int[] nums = {5, 4, 2, 4};
        System.out.println("Total Continuous Subarrays: " + countContinuousSubarrays(nums));
    }
}
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int countContinuousSubarrays(vector<int>& nums) {
    int left = 0, right = 0, count = 0;
    while (right < nums.size()) {
        int minVal = nums[right], maxVal = nums[right];
        for (int i = right; i >= left; --i) {
            maxVal = max(maxVal, nums[i]);
            minVal = min(minVal, nums[i]);
            if (maxVal - minVal <= 2) {
                count++;
            } else {
                left = i + 1;
                break;
            }
        }
        ++right;
    }
    return count;
}

int main() {
    vector<int> nums = {5, 4, 2, 4};
    cout << "Total Continuous Subarrays: " << countContinuousSubarrays(nums) << endl;
    return 0;
}
function countContinuousSubarrays(nums) {
    let left = 0;
    let right = 0;
    let count = 0;
    while (right < nums.length) {
        let minVal = nums[right], maxVal = nums[right];
        for (let i = right; i >= left; i--) {
            maxVal = Math.max(maxVal, nums[i]);
            minVal = Math.min(minVal, nums[i]);
            if (maxVal - minVal <= 2) {
                count++;
            } else {
                left = i + 1;
                break;
            }
        }
        right++;
    }
    return count;
}

const nums = [5, 4, 2, 4];
console.log("Total Continuous Subarrays:", countContinuousSubarrays(nums));
#include <stdio.h>
#include <stdlib.h>

int countContinuousSubarrays(int* nums, int numsSize) {
    int left = 0, right = 0, count = 0;
    while (right < numsSize) {
        int minVal = nums[right], maxVal = nums[right];
        for (int i = right; i >= left; i--) {
            if (nums[i] > maxVal) maxVal = nums[i];
            if (nums[i] < minVal) minVal = nums[i];
            if (maxVal - minVal <= 2) {
                count++;
            } else {
                left = i + 1;
                break;
            }
        }
        right++;
    }
    return count;
}

int main() {
    int nums[] = {5, 4, 2, 4};
    int numsSize = sizeof(nums) / sizeof(nums[0]);
    printf("Total Continuous Subarrays: %d\n", countContinuousSubarrays(nums, numsSize));
    return 0;
}
using System;

public class ContinuousSubarrays {
    public static int CountContinuousSubarrays(int[] nums) {
        int left = 0, right = 0, count = 0;
        while (right < nums.Length) {
            int minVal = nums[right], maxVal = nums[right];
            for (int i = right; i >= left; i--) {
                maxVal = Math.Max(maxVal, nums[i]);
                minVal = Math.Min(minVal, nums[i]);
                if (maxVal - minVal <= 2) {
                    count++;
                } else {
                    left = i + 1;
                    break;
                }
            }
            right++;
        }
        return count;
    }

    public static void Main() {
        int[] nums = { 5, 4, 2, 4 };
        Console.WriteLine($"Total Continuous Subarrays: {CountContinuousSubarrays(nums)}");
    }
}

In this Java implementation, the sliding window is dynamically adjusted as the max/min conditions exceed the limit. This sliding mechanism minimizes unnecessary recalculations.

Complexity

Time Complexity: O(n), derived from optimizing the index range transitions.
Space Complexity: O(1), maintains in-memory operations without extra space.

Try this approach in the editor

Approach 5: Ordered List + Two Pointers

We can use two pointers, i and j, to maintain the left and right endpoints of the current subarray, and use an ordered list to maintain all elements in the current subarray.

Iterate through the array nums. For the current number nums[i] we're iterating over, we add it to the ordered list. If the difference between the maximum and minimum values in the ordered list is greater than 2, we then loop to move the pointer i to the right, continuously removing nums[i] from the ordered list, until the list is empty or the maximum difference between elements in the ordered list is not greater than 2. At this point, the number of uninterrupted subarrays is j - i + 1, which we add to the answer.

After the iteration, return the answer.

The time complexity is O(n times log n) and the space complexity is O(n), where n is the length of the array nums.

func continuousSubarrays(nums []int) (ans int64) {
	i := 0
	tm := treemap.NewWithIntComparator()
	for j, x := range nums {
		if v, ok := tm.Get(x); ok {
			tm.Put(x, v.(int)+1)
		} else {
			tm.Put(x, 1)
		}
		for {
			a, _ := tm.Min()
			b, _ := tm.Max()
			if b.(int)-a.(int) > 2 {
				if v, _ := tm.Get(nums[i]); v.(int) == 1 {
					tm.Remove(nums[i])
				} else {
					tm.Put(nums[i], v.(int)-1)
				}
				i++
			} else {
				break
			}
		}
		ans += int64(j - i + 1)
	}
	return
}
Try this approach in the editor

Approach 6: Monotonic queue + Two Pointers

function continuousSubarrays(nums: number[]): number {
    const [minQ, maxQ]: [number[], number[]] = [[], []];
    const n = nums.length;
    let res = 0;

    for (let r = 0, l = 0; r < n; r++) {
        const x = nums[r];
        while (minQ.length && nums[minQ.at(-1)!] > x) minQ.pop();
        while (maxQ.length && nums[maxQ.at(-1)!] < x) maxQ.pop();
        minQ.push(r);
        maxQ.push(r);

        while (minQ.length && maxQ.length && nums[maxQ[0]] - nums[minQ[0]] > 2) {
            if (maxQ[0] < minQ[0]) {
                l = maxQ[0] + 1;
                maxQ.shift();
            } else {
                l = minQ[0] + 1;
                minQ.shift();
            }
        }

        res += r - l + 1;
    }

    return res;
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
Sliding Window Approach

Time Complexity: O(n) because each element is processed at most twice, once by 'start' and once by 'end'.

Space Complexity: O(1) since no additional data structures are used besides basic variables.

Brute Force Approach

Time Complexity: O(n^3) due to triple looping over the array to check all subarrays.

Space Complexity: O(1) as no extra space is used beyond variables.

Brute Force Approach

Time Complexity: O(n^3), dominated by the nested loop structure and the pair check.
Space Complexity: O(1), minimal additional space.

Sliding Window Approach

Time Complexity: O(n), derived from optimizing the index range transitions.
Space Complexity: O(1), maintains in-memory operations without extra space.

Ordered List + Two Pointers–
Monotonic queue + Two Pointers–

Complexity analysis

ApproachTimeSpaceWhen to Use
Brute ForceO(n²)O(1)Useful for understanding the constraint and verifying correctness on small inputs
Sliding Window with Monotonic QueuesO(n)O(n)Best choice for large arrays where maintaining window min and max efficiently is required

Frequently asked questions

Is Continuous Subarrays easy or hard?

Continuous Subarrays is generally classified as a Medium problem. The challenge comes from recognizing that you must track both the minimum and maximum elements efficiently while maintaining a valid sliding window.

Continuous Subarrays Python/Java solution

The typical implementation uses two pointers with deques from standard libraries. Python commonly uses collections.deque, while Java uses ArrayDeque. Both implementations maintain monotonic order while expanding and shrinking the sliding window.

How to solve Continuous Subarrays in O(n)?

Maintain a sliding window with two deques: one decreasing deque for the maximum and one increasing deque for the minimum. Expand the right pointer while updating both structures. If the difference between the front elements exceeds 2, move the left pointer and remove elements leaving the window. Count valid subarrays using right - left + 1.

What is the best approach for Continuous Subarrays?

The optimal solution uses a sliding window with two monotonic deques to maintain the current minimum and maximum values. This allows you to expand and shrink the window while ensuring the difference between max and min stays within 2. The approach runs in O(n) time because each element enters and leaves the window at most once.

Is Continuous Subarrays asked at Google/Amazon/Meta?

Problems combining sliding window techniques with monotonic queues appear frequently in interviews at companies like Amazon, Google, and Meta. Variants involving maintaining window minimum and maximum values are common systemized interview patterns.

What data structure is used in Continuous Subarrays?

The most efficient solution uses monotonic double-ended queues (deques). One deque tracks the maximum values in decreasing order, and the other tracks minimum values in increasing order. These structures allow constant-time updates and retrieval of window extremes.

What is the time complexity of Continuous Subarrays?

The optimal sliding window approach runs in O(n) time and O(n) space using two monotonic queues. A brute force approach that checks all subarrays takes O(n²) time because it expands every starting index and recalculates min and max values.

Comments

Now write it yourselfClose this page and solve Continuous Subarrays in the editor, without looking.
Practise Continuous Subarrays