Skip to content
← All posts

Longest Continuous Increasing Subsequence: Sliding Window Counter

5 min read
leetcodeproblemeasyarrays

You are given an unsorted array of integers. Find the length of the longest continuous increasing subsequence (subarray). The elements must be strictly increasing and contiguous in the original array.

This is LeetCode 674: Longest Continuous Increasing Subsequence, and it is one of the cleanest examples of a single-pass counting pattern. No extra data structures, no nested loops. Just one variable tracking the current run length and another tracking the best you have seen.

1031524374longest = 3
Input: [1, 3, 5, 4, 7]. The longest continuous increasing subarray is [1, 3, 5] with length 3.

The approach: track the current run

The idea is simple. Walk through the array from left to right, maintaining a counter for the current run of increasing elements. At each index, compare the current element to the previous one:

  • If the current element is greater than the previous element, the increasing run continues. Increment the counter.
  • Otherwise, the run is broken. Reset the counter to 1 (the current element starts a new run by itself).

After each step, update the best length if the current run beats it. When you reach the end of the array, best holds the answer.

That is the entire algorithm. One pass, two variables, done.

This problem asks for a contiguous subarray, not a subsequence. That distinction is what makes it so much simpler than the classic Longest Increasing Subsequence problem.

How this differs from LIS

The name of this problem can be confusing because it says "subsequence" but really means subarray (contiguous elements). The classic Longest Increasing Subsequence problem allows you to skip elements. You pick elements that are in order and strictly increasing, but they do not have to be next to each other. That problem needs O(n^2) DP or O(n log n) binary search.

This problem requires the elements to be adjacent. You cannot skip anything. That constraint eliminates the need for any lookback or search. You only ever compare the current element to the one right before it, which gives you O(n) time and O(1) space with no tricks needed.

Python solution

def find_length_of_lcis(nums):
    if not nums:
        return 0

    best = 1
    current = 1

    for i in range(1, len(nums)):
        if nums[i] > nums[i - 1]:
            current += 1
            best = max(best, current)
        else:
            current = 1

    return best

Four lines of logic inside the loop. Let's break it down:

  1. Handle the empty array edge case up front.
  2. Both best and current start at 1 because a single element is an increasing subarray of length 1.
  3. For each element starting at index 1, check if it continues the increasing run. If nums[i] > nums[i - 1], increment current and update best. Otherwise, reset current to 1.
  4. Return best at the end.

Walking through it step by step

Let's trace through nums = [1, 3, 5, 4, 7]. At each step we track current_len (the length of the current increasing run) and best (the longest run seen so far). Green cells show the active run. Red marks a reset.

Step 1: i = 0. Start of run.

1031524374

current_len = 1, best = 1. First element starts a run of length 1.

Step 2: i = 1 (3 > 1). Extend the run.

1031524374

current_len = 2, best = 2. 3 is greater than 1, so the run continues.

Step 3: i = 2 (5 > 3). Extend the run.

1031524374

current_len = 3, best = 3. 5 is greater than 3. This is the longest run so far.

Step 4: i = 3 (4 is not > 5). Reset the run.

1031524374

current_len = 1, best = 3. 4 is not greater than 5, so the run resets to 1.

Step 5: i = 4 (7 > 4). Extend the run.

1031524374

current_len = 2, best = 3. 7 is greater than 4, but this run of length 2 does not beat the best of 3.

The answer is 3, from the subarray [1, 3, 5].

The critical moment is step 4. When we hit 4, it is not greater than 5, so the run breaks. We reset current to 1 and start tracking a new run from index 3. The new run [4, 7] reaches length 2, but it never beats the best of 3. Without the reset logic, we would incorrectly keep counting and get the wrong answer.

Complexity analysis

Time: O(n). We visit each element exactly once. Each visit does O(1) work (one comparison and at most two updates). Total: O(n).

Space: O(1). Two variables (current and best), regardless of input size. No extra arrays, no hash maps, no stacks.

ApproachTimeSpace
Check all subarraysO(n^2)O(1)
Single pass counterO(n)O(1)

The brute force approach checks every possible starting and ending index, computing whether each subarray is increasing. The single pass counter does the same work implicitly by tracking the run as you go.

Edge cases to watch for

Before submitting, make sure your solution handles these:

  • Empty array []: return 0. The guard clause at the top catches this.
  • Single element [5]: return 1. A single element is an increasing subarray of length 1.
  • All increasing like [1, 2, 3, 4, 5]: the entire array is one run. Answer is n.
  • All decreasing like [5, 4, 3, 2, 1]: every run resets immediately. Answer is 1.
  • All equal like [3, 3, 3, 3]: equal elements are not strictly increasing. Every run resets. Answer is 1.

The single pass counter handles all of these correctly with no special cases beyond the empty array check.

The building blocks

This problem is built on one reusable pattern:

Linear scan with a running counter. You maintain a counter that grows when a condition holds and resets when it does not. At each step, you update a running best. This same skeleton shows up in Maximum Subarray (Kadane's algorithm uses extend-or-restart instead of increment-or-reset, but the shape is identical), Best Time to Buy and Sell Stock (running min instead of running counter), and many other single-pass problems.

The key insight is that you never need to look back further than one element. When the run breaks, everything before the break is irrelevant to future runs. That is what makes O(1) space possible.

From understanding to recall

You have just read through the single pass counter approach and it makes complete sense. But can you write it from scratch under pressure? The logic is short, but the details matter: initializing both variables to 1, using strict inequality, updating best inside the if branch (not after the else).

Spaced repetition is designed for exactly this. Instead of solving Longest Continuous Increasing Subsequence once and forgetting the edge cases in two weeks, you revisit the pattern at increasing intervals. Each time you write the code from memory. After a few reps, the increment-or-reset logic and the initialization are automatic.

The linear scan counter is one of roughly 60 reusable building blocks that cover hundreds of LeetCode problems. Learning them individually and drilling them with spaced repetition is far more effective than solving problems one at a time and hoping the patterns stick.

Related posts