最长连续递增序列

标签: 数组

难度: Easy

给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。

连续递增的子序列 可以由两个下标 lrl < r)确定,如果对于每个 l <= i < r,都有 nums[i] < nums[i + 1] ,那么子序列 [nums[l], nums[l + 1], ..., nums[r - 1], nums[r]] 就是连续递增子序列。

 

示例 1:

输入:nums = [1,3,5,4,7]
输出:3
解释:最长连续递增序列是 [1,3,5], 长度为3。
尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为 5 和 7 在原数组里被 4 隔开。 

示例 2:

输入:nums = [2,2,2,2,2]
输出:1
解释:最长连续递增序列是 [2], 长度为1。

 

提示:

  • 1 <= nums.length <= 104
  • -109 <= nums[i] <= 109

Submission

运行时间: 18 ms

内存: 16.9 MB

class Solution:
    def findLengthOfLCIS(self, nums: List[int]) -> int:
        left=0
        longest=0
        if len(nums)==1:
            return 1
        for right in range(1,len(nums)):
            if nums[right]>nums[right-1]:
                longest=max(longest,right-left+1)
            else:
                longest=max(longest,right-left)
                left=right
        #longest=max(longest,right-left+1)
        return longest

Explain

这个题解采用了双指针的思路。左指针 left 表示当前连续递增子序列的起始位置,右指针 right 用于遍历数组。通过比较当前元素与前一个元素的大小,可以判断是否仍然保持递增趋势。如果递增,则更新最长长度 longest。如果递增中断,则更新 left 指针到当前位置,表示重新开始寻找连续递增子序列。最后返回找到的最长连续递增子序列的长度 longest。

时间复杂度: O(n)

空间复杂度: O(1)

class Solution:
    def findLengthOfLCIS(self, nums: List[int]) -> int:
        left = 0  # 左指针,表示当前连续递增子序列的起始位置
        longest = 0  # 记录最长连续递增子序列的长度
        if len(nums) == 1:
            return 1
        for right in range(1, len(nums)):  # 右指针,用于遍历数组
            if nums[right] > nums[right - 1]:  # 如果当前元素大于前一个元素,说明递增序列继续
                longest = max(longest, right - left + 1)  # 更新最长长度
            else:  # 如果递增中断
                longest = max(longest, right - left)  # 更新最长长度
                left = right  # 将左指针移动到当前位置,重新开始寻找连续递增子序列
        return longest

Explore

这实际上是题解中的一个错误。在递增中断时,正确的做法应该是使用 `right-left+1` 来计算长度,因为 `left` 和 `right` 之间的距离需要包括 `left` 所指向的元素。例如,如果 `left` 指向索引 0 而 `right` 指向索引 1,此时子序列包含两个元素,应该使用 `right-left+1` 计算长度为 2。

是的,题解中的方法能正确处理这种情况并返回长度为 1。因为每次当 `nums[right]` 不大于 `nums[right-1]` 时,左指针 `left` 会更新到 `right` 的位置,因此对于所有相同元素的数组,每次比较都会导致 `left` 更新,每个独立元素都被视为长度为 1 的连续递增子序列。

是的,这是一个通用的边界条件处理。对于任何长度为 1 的数组,由于没有其他元素与之比较,这单个元素自成一段连续递增子序列,长度自然为 1。这种处理是简洁且有效的,适用于所有长度为 1 的数组情况。

是的,代码中的更新逻辑可以进行优化以简化代码。可以在循环结束后进行一次更新,而不是在循环的每个步骤中都进行。具体来说,可以在循环外部再添加一次 `longest = max(longest, right - left + 1)` 的操作,以确保最后一个连续递增子序列也被计算在内。这样,就无需在每个递增和中断点都更新 `longest`,从而简化代码。