Facebook Pixel

2760. Longest Even Odd Subarray With Threshold

Problem Description

You are given an integer array nums (0-indexed) and an integer threshold. Your task is to find the length of the longest subarray that satisfies all of the following conditions:

  1. The subarray must start with an even number: The first element of the subarray (nums[l]) must be even, meaning nums[l] % 2 == 0

  2. Elements must alternate between even and odd: For any two consecutive elements in the subarray, one must be even and the other must be odd. In other words, for all indices i in the range [l, r-1], we need nums[i] % 2 != nums[i+1] % 2

  3. All elements must not exceed the threshold: Every element in the subarray must be less than or equal to threshold. For all indices i in the range [l, r], we need nums[i] <= threshold

The goal is to return the length of the longest subarray that meets all these requirements. If no such subarray exists, return 0.

For example, if nums = [3, 2, 5, 4] and threshold = 5:

  • A valid subarray could be [2, 5, 4] starting at index 1, which has length 3
  • It starts with 2 (even), alternates (2-even, 5-odd, 4-even), and all elements are ≤ 5

The solution approach iterates through each possible starting position l. When a valid starting position is found (even number ≤ threshold), it extends the subarray as far as possible while maintaining the alternating pattern and threshold constraint, keeping track of the maximum length found.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The key insight is that every valid subarray must start with an even number. This gives us a natural starting point - we can check each position in the array to see if it could be the beginning of a valid subarray.

Think about it this way: if we're standing at any position l in the array and nums[l] is even and within the threshold, we've found a potential starting point. From here, we want to extend the subarray as far as possible to the right while maintaining the alternating pattern and staying within the threshold.

The alternating pattern means that if we start with an even number, the next must be odd, then even again, and so on. We can check this by comparing nums[r] % 2 with nums[r-1] % 2 - they should always be different for consecutive elements.

Why does this brute force approach work well? Because once we violate any condition while extending from position l, we can't fix it by extending further. The subarray from l has reached its maximum possible length. We then move to the next potential starting position and repeat the process.

The beauty of this approach is its simplicity - we're essentially asking: "For each valid starting position, how far can I extend?" We don't need complex dynamic programming or data structures because the constraints are local (each element compared to threshold, consecutive elements compared to each other for parity).

By trying all possible starting positions and finding the maximum length achievable from each, we guarantee finding the overall longest valid subarray. The time complexity of O(n²) in the worst case is acceptable since we're doing a straightforward scan for each starting position.

Learn more about Sliding Window patterns.

Solution Approach

The implementation uses a straightforward enumeration approach where we check every possible starting position for a valid subarray.

Step-by-step implementation:

  1. Initialize variables: We set ans = 0 to track the maximum length found, and n = len(nums) for the array size.

  2. Enumerate all possible starting positions: We iterate through each index l from 0 to n-1 as a potential starting point.

  3. Check starting position validity: For each l, we verify if nums[l] meets our starting conditions:

    • nums[l] % 2 == 0 (must be even)
    • nums[l] <= threshold (must not exceed threshold)
  4. Extend the subarray: If l is a valid starting point, we initialize r = l + 1 and try to extend the subarray to the right. We continue extending while:

    • r < n (within array bounds)
    • nums[r] % 2 != nums[r-1] % 2 (maintains alternating pattern)
    • nums[r] <= threshold (stays within threshold)
  5. Update maximum length: Once we can't extend further from position l, we calculate the subarray length as r - l and update ans = max(ans, r - l).

  6. Return result: After checking all possible starting positions, we return ans.

Why this works:

The algorithm systematically checks every valid subarray by:

  • Starting only at positions with even numbers (condition 1)
  • Extending only while alternation is maintained (condition 2)
  • Stopping when threshold is exceeded (condition 3)

Since we examine all possible valid subarrays and keep track of the maximum length, we're guaranteed to find the optimal answer. The nested loop structure (outer loop for starting positions, inner while loop for extending) ensures we don't miss any valid subarray.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through the solution with nums = [3, 2, 5, 4, 7, 6] and threshold = 6.

Starting from index 0 (nums[0] = 3):

  • 3 is odd, so it cannot be a valid starting point (must start with even)
  • Skip to next position

Starting from index 1 (nums[1] = 2):

  • 2 is even ✓ and 2 ≤ 6 ✓
  • Valid starting point found, begin extending:
    • r = 2: nums[2] = 5, check: 5 ≤ 6 ✓ and 5 % 2 (odd) ≠ 2 % 2 (even) ✓
    • r = 3: nums[3] = 4, check: 4 ≤ 6 ✓ and 4 % 2 (even) ≠ 5 % 2 (odd) ✓
    • r = 4: nums[4] = 7, check: 7 ≤ 6 ✗ (exceeds threshold)
  • Stop extending, subarray length = 3 - 1 = 3
  • Update ans = max(0, 3) = 3

Starting from index 2 (nums[2] = 5):

  • 5 is odd, skip

Starting from index 3 (nums[3] = 4):

  • 4 is even ✓ and 4 ≤ 6 ✓
  • Valid starting point, begin extending:
    • r = 4: nums[4] = 7, check: 7 ≤ 6 ✗
  • Stop extending, subarray length = 4 - 3 = 1
  • ans remains 3

Starting from index 4 (nums[4] = 7):

  • 7 > 6, exceeds threshold, skip

Starting from index 5 (nums[5] = 6):

  • 6 is even ✓ and 6 ≤ 6 ✓
  • Valid starting point, but r = 6 is out of bounds
  • Subarray length = 6 - 5 = 1
  • ans remains 3

Result: The longest valid subarray is [2, 5, 4] with length 3.

Solution Implementation

1class Solution:
2    def longestAlternatingSubarray(self, nums: List[int], threshold: int) -> int:
3        """
4        Find the longest alternating subarray starting with an even number
5        where all elements are <= threshold.
6      
7        Args:
8            nums: List of integers
9            threshold: Maximum allowed value for elements in the subarray
10          
11        Returns:
12            Length of the longest valid alternating subarray
13        """
14        max_length = 0
15        n = len(nums)
16      
17        # Try each position as a potential starting point
18        for left in range(n):
19            # Valid subarray must start with an even number <= threshold
20            if nums[left] % 2 == 0 and nums[left] <= threshold:
21                # Extend the subarray as far as possible
22                right = left + 1
23              
24                # Continue while elements alternate between even/odd and are <= threshold
25                while (right < n and 
26                       nums[right] % 2 != nums[right - 1] % 2 and 
27                       nums[right] <= threshold):
28                    right += 1
29              
30                # Update the maximum length found
31                current_length = right - left
32                max_length = max(max_length, current_length)
33      
34        return max_length
35
1class Solution {
2    public int longestAlternatingSubarray(int[] nums, int threshold) {
3        int maxLength = 0;
4        int arrayLength = nums.length;
5      
6        // Iterate through each possible starting position
7        for (int left = 0; left < arrayLength; ++left) {
8            // Check if current element can be a valid start:
9            // 1. Must be even (starts with even number)
10            // 2. Must not exceed threshold
11            if (nums[left] % 2 == 0 && nums[left] <= threshold) {
12                // Initialize right pointer to explore the subarray
13                int right = left + 1;
14              
15                // Extend the subarray while conditions are met:
16                // 1. Within array bounds
17                // 2. Current and previous elements have different parity (alternating)
18                // 3. Current element doesn't exceed threshold
19                while (right < arrayLength && 
20                       nums[right] % 2 != nums[right - 1] % 2 && 
21                       nums[right] <= threshold) {
22                    ++right;
23                }
24              
25                // Update maximum length found so far
26                maxLength = Math.max(maxLength, right - left);
27            }
28        }
29      
30        return maxLength;
31    }
32}
33
1class Solution {
2public:
3    int longestAlternatingSubarray(vector<int>& nums, int threshold) {
4        int maxLength = 0;
5        int arraySize = nums.size();
6      
7        // Try each position as a potential starting point
8        for (int left = 0; left < arraySize; ++left) {
9            // Check if current position can be a valid start:
10            // 1. Must be even
11            // 2. Must not exceed threshold
12            if (nums[left] % 2 == 0 && nums[left] <= threshold) {
13                // Extend the subarray as far as possible
14                int right = left + 1;
15              
16                // Continue extending while:
17                // 1. Within array bounds
18                // 2. Parity alternates (current and previous have different parity)
19                // 3. Current element doesn't exceed threshold
20                while (right < arraySize && 
21                       nums[right] % 2 != nums[right - 1] % 2 && 
22                       nums[right] <= threshold) {
23                    ++right;
24                }
25              
26                // Update maximum length found so far
27                maxLength = max(maxLength, right - left);
28            }
29        }
30      
31        return maxLength;
32    }
33};
34
1/**
2 * Finds the length of the longest alternating subarray that starts with an even number
3 * and all elements are less than or equal to the threshold.
4 * 
5 * @param nums - The input array of numbers
6 * @param threshold - The maximum allowed value for elements in the subarray
7 * @returns The length of the longest valid alternating subarray
8 */
9function longestAlternatingSubarray(nums: number[], threshold: number): number {
10    const arrayLength: number = nums.length;
11    let maxLength: number = 0;
12  
13    // Iterate through each possible starting position
14    for (let leftIndex: number = 0; leftIndex < arrayLength; leftIndex++) {
15        // Check if current element can be a valid start:
16        // 1. Must be even
17        // 2. Must be within threshold
18        if (nums[leftIndex] % 2 === 0 && nums[leftIndex] <= threshold) {
19            // Initialize right pointer to explore the alternating pattern
20            let rightIndex: number = leftIndex + 1;
21          
22            // Extend the subarray while conditions are met:
23            // 1. Elements alternate between even and odd
24            // 2. Elements are within threshold
25            while (rightIndex < arrayLength && 
26                   nums[rightIndex] % 2 !== nums[rightIndex - 1] % 2 && 
27                   nums[rightIndex] <= threshold) {
28                rightIndex++;
29            }
30          
31            // Update maximum length found so far
32            const currentLength: number = rightIndex - leftIndex;
33            maxLength = Math.max(maxLength, currentLength);
34        }
35    }
36  
37    return maxLength;
38}
39

Time and Space Complexity

The time complexity is O(n²), where n is the length of the array nums.

The algorithm uses a nested loop structure: the outer loop iterates through each index l from 0 to n-1, and for each valid starting position (where nums[l] % 2 == 0 and nums[l] <= threshold), the inner while loop extends the subarray by incrementing r until the alternating pattern breaks or the threshold is exceeded. In the worst case, for each starting position l, the inner loop can iterate up to n - l - 1 times. This gives us a total time complexity of O(n) * O(n) = O(n²).

The space complexity is O(1).

The algorithm only uses a constant amount of extra space for variables ans, n, l, and r, regardless of the input size. No additional data structures that scale with the input are created.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Forgetting to check threshold condition for the starting element

A common mistake is only checking if nums[left] is even when determining a valid starting position, but forgetting to also verify nums[left] <= threshold.

Incorrect code:

# Missing threshold check for starting element
if nums[left] % 2 == 0:  # Only checking if even
    right = left + 1
    while (right < n and 
           nums[right] % 2 != nums[right - 1] % 2 and 
           nums[right] <= threshold):
        right += 1

Why this fails: If nums[left] is even but exceeds the threshold (e.g., nums[left] = 10, threshold = 5), the subarray violates condition 3 from the start.

Solution: Always check both conditions for the starting element:

if nums[left] % 2 == 0 and nums[left] <= threshold:
    # Now we can safely start extending

2. Incorrect alternation check using the wrong index

Another pitfall is using the wrong indices when checking the alternation pattern, such as comparing nums[right] with nums[left] instead of nums[right - 1].

Incorrect code:

while (right < n and 
       nums[right] % 2 != nums[left] % 2 and  # Wrong! Comparing with left
       nums[right] <= threshold):
    right += 1

Why this fails: This only ensures nums[right] has different parity from nums[left], not that consecutive elements alternate. For example, with [2, 4, 3], this would incorrectly accept [2, 4] as valid since 4 has different parity from 2, even though 2 and 4 are both even.

Solution: Always compare consecutive elements:

while (right < n and 
       nums[right] % 2 != nums[right - 1] % 2 and  # Correct adjacency check
       nums[right] <= threshold):
    right += 1

3. Off-by-one error when calculating subarray length

Some might incorrectly calculate the length as right - left + 1 after the while loop ends.

Incorrect code:

current_length = right - left + 1  # Wrong! Off by one
max_length = max(max_length, current_length)

Why this fails: When the while loop exits, right points to the first invalid position (or n if we reached the end). The valid subarray spans from left to right - 1, so the length is right - left, not right - left + 1.

Solution: Use the correct formula:

current_length = right - left  # Correct length calculation
max_length = max(max_length, current_length)
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

Given a sorted array of integers and an integer called target, find the element that equals to the target and return its index. Select the correct code that fills the ___ in the given code snippet.

1def binary_search(arr, target):
2    left, right = 0, len(arr) - 1
3    while left ___ right:
4        mid = (left + right) // 2
5        if arr[mid] == target:
6            return mid
7        if arr[mid] < target:
8            ___ = mid + 1
9        else:
10            ___ = mid - 1
11    return -1
12
1public static int binarySearch(int[] arr, int target) {
2    int left = 0;
3    int right = arr.length - 1;
4
5    while (left ___ right) {
6        int mid = left + (right - left) / 2;
7        if (arr[mid] == target) return mid;
8        if (arr[mid] < target) {
9            ___ = mid + 1;
10        } else {
11            ___ = mid - 1;
12        }
13    }
14    return -1;
15}
16
1function binarySearch(arr, target) {
2    let left = 0;
3    let right = arr.length - 1;
4
5    while (left ___ right) {
6        let mid = left + Math.trunc((right - left) / 2);
7        if (arr[mid] == target) return mid;
8        if (arr[mid] < target) {
9            ___ = mid + 1;
10        } else {
11            ___ = mid - 1;
12        }
13    }
14    return -1;
15}
16

Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More