A clear explanation of finding the longest strictly increasing contiguous subarray using a single scan.
Problem Restatement
We are given an unsorted integer array nums.
We need to return the length of the longest continuous increasing subsequence.
Here, continuous means the elements must be adjacent in the original array. So this is really asking for the longest strictly increasing subarray. The official statement defines it as a continuous subarray where each next element is strictly greater than the previous one.
Input and Output
| Item | Meaning |
|---|---|
| Input | An integer array nums |
| Output | Length of the longest continuous increasing subsequence |
| Continuous rule | Elements must be adjacent |
| Increasing rule | Each next value must be strictly greater |
| Equal values | Break the increasing run |
Example function shape:
def findLengthOfLCIS(nums: list[int]) -> int:
...Examples
Consider:
nums = [1, 3, 5, 4, 7]The longest continuous increasing subsequence is:
1, 3, 5Its length is:
3Even though:
1, 3, 5, 7is an increasing subsequence, it is not continuous because 5 and 7 are separated by 4.
So the answer is:
3Another example:
nums = [2, 2, 2, 2, 2]The sequence must be strictly increasing.
Equal values do not continue the run.
So the longest continuous increasing subsequence has length:
1First Thought: Check Every Subarray
A direct solution is to try every subarray and check whether it is strictly increasing.
For each starting index, we can extend right while the values keep increasing.
This works, but it repeats work.
If the array has length n, checking all subarrays can take:
O(n^2)We can do better because an increasing run can be tracked while scanning once.
Key Insight
A continuous increasing subsequence only depends on adjacent comparisons.
When we are at index i, there are two cases:
- If
nums[i] > nums[i - 1], the current increasing run continues. - Otherwise, the current run breaks and must restart at
nums[i].
So we only need two variables:
| Variable | Meaning |
|---|---|
current | Length of the increasing run ending at the current index |
answer | Best run length seen so far |
Algorithm
- If
numsis empty, return0. - Set
current = 1. - Set
answer = 1. - Scan from index
1to the end. - If
nums[i] > nums[i - 1], increasecurrent. - Otherwise, reset
currentto1. - Update
answer. - Return
answer.
Correctness
At every index i, current stores the length of the longest continuous strictly increasing subarray that ends at i.
If nums[i] > nums[i - 1], then any increasing run ending at i - 1 can be extended by nums[i], so current increases by 1.
If nums[i] <= nums[i - 1], then no continuous increasing subarray ending at i can include nums[i - 1], so the best run ending at i has length 1.
The variable answer is updated after every index, so it stores the maximum length among all increasing runs seen so far.
Therefore, after the scan finishes, answer is exactly the length of the longest continuous increasing subsequence.
Complexity
| Metric | Value | Why |
|---|---|---|
| Time | O(n) | Each element is processed once |
| Space | O(1) | Only two counters are used |
Implementation
from typing import List
class Solution:
def findLengthOfLCIS(self, nums: List[int]) -> int:
if not nums:
return 0
current = 1
answer = 1
for i in range(1, len(nums)):
if nums[i] > nums[i - 1]:
current += 1
else:
current = 1
answer = max(answer, current)
return answerCode Explanation
We handle an empty array first:
if not nums:
return 0Then we initialize both counters to 1:
current = 1
answer = 1A single element is always a valid continuous increasing subsequence.
We scan from the second element:
for i in range(1, len(nums)):If the current value is greater than the previous value, the run continues:
if nums[i] > nums[i - 1]:
current += 1Otherwise, the run breaks:
else:
current = 1After each step, update the best length:
answer = max(answer, current)Finally, return the best run length.
Testing
def run_tests():
s = Solution()
assert s.findLengthOfLCIS([1, 3, 5, 4, 7]) == 3
assert s.findLengthOfLCIS([2, 2, 2, 2, 2]) == 1
assert s.findLengthOfLCIS([1, 2, 3, 4, 5]) == 5
assert s.findLengthOfLCIS([5, 4, 3, 2, 1]) == 1
assert s.findLengthOfLCIS([1]) == 1
assert s.findLengthOfLCIS([]) == 0
assert s.findLengthOfLCIS([1, 3, 5, 7, 2, 4, 6, 8]) == 4
print("all tests passed")
run_tests()Test meaning:
| Test | Why |
|---|---|
[1,3,5,4,7] | Standard example |
[2,2,2,2,2] | Equal values break strict increase |
| Already increasing | Whole array is the answer |
| Strictly decreasing | Every run has length 1 |
| Single element | Smallest non-empty input |
| Empty array | Defensive local test |
| Two increasing runs | Confirms maximum run is selected |