Facebook Pixel

674. Longest Continuous Increasing Subsequence

Problem Description

You are given an unsorted array of integers nums. Your task is to find the length of the longest continuous increasing subsequence (subarray) in the array. The subsequence must be strictly increasing.

A continuous increasing subsequence is a subarray defined by two indices l and r (where l < r) such that the subarray is [nums[l], nums[l + 1], ..., nums[r - 1], nums[r]], and for each position i where l <= i < r, we have nums[i] < nums[i + 1].

In other words, you need to find the maximum length of a subarray where each element is strictly greater than the previous element. The elements must be consecutive in the original array (not just any subsequence, but a contiguous subarray).

For example:

  • If nums = [1, 3, 5, 4, 7], the longest continuous increasing subsequence is [1, 3, 5] with length 3
  • If nums = [2, 2, 2, 2, 2], since no element is strictly greater than the previous, the answer would be 1 (any single element forms a valid subsequence)

The solution uses a single pass through the array, maintaining a counter cnt for the current increasing sequence length. Whenever we find an element greater than the previous one, we increment the counter and update the maximum length seen so far. When we encounter an element that's not greater than the previous one, we reset the counter to 1 and start counting a new sequence.

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

Intuition

The key insight is that we need to find contiguous subarrays where each element is strictly greater than the previous one. Since we're looking for continuous subsequences, we can solve this problem in a single pass through the array.

Think about how you would manually find the longest increasing subarray: you'd start from the beginning and keep counting consecutive increasing elements. When you hit an element that's not greater than the previous one, you'd note down the length you've found so far and start counting again from that position.

This naturally leads to a greedy approach: maintain a running count of the current increasing sequence. As we traverse the array from left to right:

  • If nums[i] > nums[i-1], the current element extends our increasing sequence, so we increment our counter
  • If nums[i] <= nums[i-1], the increasing sequence is broken, so we reset our counter to 1 (starting a new sequence with just the current element)

Throughout this process, we keep track of the maximum length we've seen. This works because:

  1. Every increasing subsequence must start somewhere and end somewhere
  2. Once a sequence is broken (by a non-increasing element), there's no way to "repair" it - we must start counting a new sequence
  3. By checking every possible starting point (which happens naturally when we reset the counter), we're guaranteed to find the maximum length

The beauty of this approach is its simplicity - we only need to compare adjacent elements and maintain two variables: the current sequence length cnt and the maximum length seen so far ans. This gives us an optimal O(n) time complexity with O(1) space.

Solution Approach

We implement a one-pass scan algorithm that traverses the array while maintaining two variables:

  • cnt: tracks the length of the current consecutive increasing sequence
  • ans: stores the maximum length found so far

Implementation Steps:

  1. Initialize variables: Set both ans = 1 and cnt = 1. This handles the edge case where the array has only one element, and initializes our current sequence counter.

  2. Traverse the array: Starting from index 1 (or enumerate from nums[1:]), we compare each element with its predecessor:

    for i, x in enumerate(nums[1:]):

    Note that when enumerating nums[1:], the index i corresponds to the position in the sliced array, so nums[i] actually refers to the element just before x in the original array.

  3. Check if sequence continues: For each element x at position i+1 in the original array:

    • If nums[i] < x: The current element is greater than the previous one, so the increasing sequence continues
      • Increment cnt by 1: cnt += 1
      • Update the maximum length: ans = max(ans, cnt)
    • Otherwise (nums[i] >= x): The sequence is broken
      • Reset cnt = 1 to start counting a new sequence from the current element
  4. Return the result: After traversing the entire array, ans contains the length of the longest continuous increasing subsequence.

Why this works:

  • By comparing adjacent elements, we can immediately determine if a sequence continues or breaks
  • Resetting cnt = 1 when the sequence breaks ensures we start counting fresh from that position
  • Continuously updating ans with max(ans, cnt) ensures we never lose track of the longest sequence found
  • The algorithm processes each element exactly once, giving us O(n) time complexity with O(1) extra space

The elegance of this solution lies in its simplicity - we only need to track the current sequence length and update our answer whenever we find a longer sequence.

Ready to land your dream job?

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

Start Evaluator

Example Walkthrough

Let's walk through the algorithm with nums = [1, 3, 5, 4, 7, 8, 2]:

Initial State:

  • ans = 1 (maximum length found)
  • cnt = 1 (current sequence length)

Step 1: Compare nums[0]=1 with nums[1]=3

  • Since 1 < 3, the sequence continues
  • cnt = 2 (increment counter)
  • ans = max(1, 2) = 2 (update maximum)

Step 2: Compare nums[1]=3 with nums[2]=5

  • Since 3 < 5, the sequence continues
  • cnt = 3 (increment counter)
  • ans = max(2, 3) = 3 (update maximum)

Step 3: Compare nums[2]=5 with nums[3]=4

  • Since 5 ≥ 4, the sequence breaks
  • cnt = 1 (reset counter for new sequence starting at 4)
  • ans = 3 (no update needed)

Step 4: Compare nums[3]=4 with nums[4]=7

  • Since 4 < 7, the sequence continues
  • cnt = 2 (increment counter)
  • ans = max(3, 2) = 3 (no change)

Step 5: Compare nums[4]=7 with nums[5]=8

  • Since 7 < 8, the sequence continues
  • cnt = 3 (increment counter)
  • ans = max(3, 3) = 3 (no change)

Step 6: Compare nums[5]=8 with nums[6]=2

  • Since 8 ≥ 2, the sequence breaks
  • cnt = 1 (reset counter for new sequence starting at 2)
  • ans = 3 (no update needed)

Result: The longest continuous increasing subsequence has length 3, which corresponds to either [1, 3, 5] or [4, 7, 8].

Solution Implementation

1class Solution:
2    def findLengthOfLCIS(self, nums: List[int]) -> int:
3        # Handle edge case of empty array
4        if not nums:
5            return 0
6      
7        # Initialize variables
8        # max_length: tracks the maximum length of increasing subsequence found
9        # current_length: tracks the length of current increasing subsequence
10        max_length = 1
11        current_length = 1
12      
13        # Iterate through the array starting from the second element
14        for i in range(1, len(nums)):
15            # Check if current element is greater than previous element
16            if nums[i - 1] < nums[i]:
17                # Extend the current increasing subsequence
18                current_length += 1
19                # Update maximum length if current sequence is longer
20                max_length = max(max_length, current_length)
21            else:
22                # Reset current length when sequence breaks
23                current_length = 1
24      
25        return max_length
26
1class Solution {
2    /**
3     * Finds the length of the longest continuous increasing subsequence (LCIS).
4     * A continuous increasing subsequence is defined as a subarray where each element
5     * is strictly greater than the previous element.
6     * 
7     * @param nums the input array of integers
8     * @return the length of the longest continuous increasing subsequence
9     */
10    public int findLengthOfLCIS(int[] nums) {
11        // Initialize the maximum length to 1 (minimum possible length)
12        int maxLength = 1;
13      
14        // Current consecutive increasing sequence length
15        int currentLength = 1;
16      
17        // Iterate through the array starting from the second element
18        for (int i = 1; i < nums.length; i++) {
19            // Check if current element is greater than the previous element
20            if (nums[i - 1] < nums[i]) {
21                // Extend the current increasing sequence
22                currentLength++;
23                // Update maximum length if current sequence is longer
24                maxLength = Math.max(maxLength, currentLength);
25            } else {
26                // Reset current sequence length when the increasing pattern breaks
27                currentLength = 1;
28            }
29        }
30      
31        return maxLength;
32    }
33}
34
1class Solution {
2public:
3    int findLengthOfLCIS(vector<int>& nums) {
4        // Initialize the maximum length to 1 (single element is always increasing)
5        int maxLength = 1;
6      
7        // Track the current increasing subsequence length
8        int currentLength = 1;
9      
10        // Iterate through the array starting from the second element
11        for (int i = 1; i < nums.size(); ++i) {
12            // Check if current element is greater than previous element
13            if (nums[i - 1] < nums[i]) {
14                // Extend the current increasing subsequence
15                currentLength++;
16                // Update maximum length if current sequence is longer
17                maxLength = max(maxLength, currentLength);
18            } else {
19                // Reset current length when sequence breaks
20                currentLength = 1;
21            }
22        }
23      
24        return maxLength;
25    }
26};
27
1/**
2 * Finds the length of the longest continuous increasing subsequence (LCIS)
3 * @param nums - The input array of numbers
4 * @returns The length of the longest continuous increasing subsequence
5 */
6function findLengthOfLCIS(nums: number[]): number {
7    // Initialize the maximum length and current sequence length
8    let maxLength: number = 1;
9    let currentLength: number = 1;
10  
11    // Iterate through the array starting from the second element
12    for (let i: number = 1; i < nums.length; i++) {
13        // Check if current element is greater than previous element
14        if (nums[i - 1] < nums[i]) {
15            // Increment current sequence length
16            currentLength++;
17            // Update maximum length if current sequence is longer
18            maxLength = Math.max(maxLength, currentLength);
19        } else {
20            // Reset current sequence length when sequence breaks
21            currentLength = 1;
22        }
23    }
24  
25    return maxLength;
26}
27

Time and Space Complexity

The time complexity is O(n), where n is the length of the array nums. The algorithm iterates through the array exactly once using the enumerate function starting from index 1 (via nums[1:]), performing constant-time operations (comparison, increment, and max) for each element.

The space complexity is O(1). The algorithm only uses a fixed amount of extra space for variables ans, cnt, i, and x, regardless of the input size. The slicing operation nums[1:] in the enumerate function doesn't create a new list in this context as enumerate handles it efficiently through iteration.

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

Common Pitfalls

1. Off-by-One Error with Index Comparison

A frequent mistake occurs when using enumerate(nums[1:]) and incorrectly referencing array elements:

Incorrect Implementation:

for i, x in enumerate(nums[1:]):
    if nums[i+1] < x:  # Wrong! i+1 goes out of bounds
        cnt += 1

The Problem: When enumerating nums[1:], the index i starts from 0 but refers to positions in the sliced array. To access the previous element in the original array, you should use nums[i], not nums[i+1].

Correct Approach:

# Option 1: Use enumerate with proper indexing
for i, x in enumerate(nums[1:]):
    if nums[i] < x:  # nums[i] is the previous element
        cnt += 1

# Option 2: Use range-based iteration (clearer)
for i in range(1, len(nums)):
    if nums[i-1] < nums[i]:
        cnt += 1

2. Forgetting to Update Maximum Before Resetting

Some implementations update the maximum only when the sequence continues, missing the final sequence:

Incorrect Implementation:

for i in range(1, len(nums)):
    if nums[i-1] < nums[i]:
        current_length += 1
        max_length = max(max_length, current_length)
    else:
        current_length = 1
        # Forgot to update max_length here!

The Problem: If the longest sequence ends at the last element, we never update max_length after the final increment.

Correct Approach: Either update max_length in both branches or add a final check after the loop:

# Option 1: Update in both branches
if nums[i-1] < nums[i]:
    current_length += 1
else:
    max_length = max(max_length, current_length)
    current_length = 1
max_length = max(max_length, current_length)  # Final check

# Option 2: Always update when incrementing (as shown in original solution)
if nums[i-1] < nums[i]:
    current_length += 1
    max_length = max(max_length, current_length)

3. Incorrect Handling of Empty or Single-Element Arrays

Failing to handle edge cases properly:

Incorrect Implementation:

def findLengthOfLCIS(self, nums):
    max_length = 1
    current_length = 1
  
    for i in range(1, len(nums)):  # Crashes if nums is empty!
        # ...

Correct Approach:

def findLengthOfLCIS(self, nums):
    if not nums:
        return 0
    if len(nums) == 1:
        return 1
    # ... rest of the logic

4. Using Non-Strict Comparison

Using <= instead of < for the increasing condition:

Incorrect:

if nums[i-1] <= nums[i]:  # Wrong! Must be strictly increasing
    current_length += 1

Correct:

if nums[i-1] < nums[i]:  # Strictly less than
    current_length += 1

This mistake would count sequences with equal consecutive elements as increasing, which violates the problem's requirement for strictly increasing subsequences.

Discover Your Strengths and Weaknesses: Take Our 3-Minute Quiz to Tailor Your Study Plan:

Which of these properties could exist for a graph but not a tree?


Recommended Readings

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

Load More