检测相邻递增子数组 II - LeetCode 3350 解题思路与代码解析

检测相邻递增子数组 II - LeetCode 3350 解题思路与代码解析

在本篇博客中,我们将深入解析一道中等难度的算法题------检测相邻递增子数组 II。通过这道题,我们将学习如何高效地处理数组中的递增子数组问题,并理解解决该问题的最佳策略。

题目描述

给定一个由 n 个整数组成的数组 nums,请你找出 k 的最大值,使得存在两个相邻且长度为 k 的严格递增子数组。具体来说,需要检查是否存在从下标 ab (a < b) 开始的两个子数组,并满足下述全部条件:

  1. 这两个子数组 nums[a..a + k - 1]nums[b..b + k - 1] 都是严格递增的。
  2. 这两个子数组必须是相邻 的,即 b = a + k

子数组是数组中的一个连续非空的元素序列。

示例

示例 1:

输入:nums = [2,5,7,8,9,2,3,4,3,1]
输出:3
解释:
从下标 2 开始的子数组是 [7, 8, 9],它是严格递增的。
从下标 5 开始的子数组是 [2, 3, 4],它也是严格递增的。
这两个子数组是相邻的,因此 3 是满足题目条件的最大 k 值。

示例 2:

输入:nums = [1,2,3,4,4,4,4,5,6,7]
输出:2
解释:
从下标 0 开始的子数组是 [1, 2],它是严格递增的。
从下标 2 开始的子数组是 [3, 4],它也是严格递增的。
这两个子数组是相邻的,因此 2 是满足题目条件的最大 k 值。

提示

  • 2 <= nums.length <= 2 * 10^5
  • -10^9 <= nums[i] <= 10^9

解题思路

要找到满足条件的最大 k,即存在两个相邻且长度为 k 的严格递增子数组,我们需要有效地遍历数组,并跟踪每个严格递增子数组的长度。

关键点在于:

  1. 识别严格递增的子数组:我们需要遍历数组,识别出所有严格递增的子数组,并记录它们的长度。
  2. 检查相邻性:确保找到的两个子数组是相邻的,即第二个子数组紧跟在第一个子数组的后面。
  3. 寻找最大 k :在所有可能的相邻子数组对中,找到最大的 k 值。

为了实现上述目标,我们可以采用以下策略:

  • 遍历数组:逐个元素检查当前元素是否比前一个元素大,以确定是否延续了当前的递增子数组。
  • 记录递增子数组的长度:当遇到不再递增的元素时,记录当前递增子数组的长度,并重置计数器以开始新的子数组。
  • 比较相邻子数组的长度 :每次记录一个递增子数组的长度时,与之前一个子数组的长度进行比较,更新 k 的值。

代码解析

以下是解决该问题的 Python 代码实现:

python 复制代码
class Solution:
    def maxIncreasingSubarrays(self, nums: List[int]) -> int:
        n = len(nums)
        ans = pre_cnt = cnt = 0
        for i, x in enumerate(nums):
            cnt += 1
            # 如果当前元素是最后一个,或者下一个元素不再递增
            if i == n - 1 or x >= nums[i + 1]:
                # 计算可能的 k 值
                # cnt // 2 是因为需要两个子数组,每个至少长度 k
                # min(pre_cnt, cnt) 确保两个子数组长度一致
                ans = max(ans, cnt // 2, min(pre_cnt, cnt))
                pre_cnt = cnt
                cnt = 0
        return ans

代码详解

  1. 初始化变量

    • n:数组的长度。
    • ans:存储当前找到的最大 k 值。
    • pre_cnt:记录上一个严格递增子数组的长度。
    • cnt:当前正在计数的严格递增子数组的长度。
  2. 遍历数组

    • 使用 enumerate 函数遍历数组的每个元素及其索引。
    • 对于每个元素 x,将 cnt 增加 1,表示当前递增子数组长度增加。
  3. 检测递增子数组的结束

    • 如果当前元素是最后一个元素 (i == n - 1),或者当前元素不小于下一个元素 (x >= nums[i + 1]),则说明当前递增子数组结束。
  4. 更新最大 k

    • 计算 cnt // 2,因为需要两个子数组,每个至少长度 k
    • pre_cntcnt 的最小值,确保两个子数组的长度一致。
    • 更新 ans 为当前找到的最大值。
  5. 重置计数器

    • pre_cnt 更新为当前的 cnt,为下一个递增子数组做准备。
    • cnt 重置为 0,开始新的计数。
  6. 返回结果

    • 最终返回 ans,即满足条件的最大 k 值。

示例解析

示例 1

输入:nums = [2,5,7,8,9,2,3,4,3,1]
  • 递增子数组识别:

    • [2,5,7,8,9] 长度为 5
    • [2,3,4] 长度为 3
    • [3] 长度为 1
    • [1] 长度为 1
  • 相邻子数组对:

    • [2,5,7,8,9][2,3,4]:k = min(5,3) = 3
  • 最大 k 为 3。

示例 2

输入:nums = [1,2,3,4,4,4,4,5,6,7]
  • 递增子数组识别:

    • [1,2,3,4] 长度为 4
    • [4] 长度为 1
    • [4] 长度为 1
    • [4,5,6,7] 长度为 4
  • 相邻子数组对:

    • [1,2,3,4][4]:k = min(4,1) = 1
    • [4][4]:k = min(1,1) = 1
    • [4][4,5,6,7]:k = min(1,4) = 1
  • 最大 k 为 1。

注意 :在第二个示例中,虽然 [1,2,3,4][4,5,6,7] 都是严格递增的,但它们不是直接相邻的,因为中间有一个单独的 [4]

复杂度分析

  • 时间复杂度O(n),其中 n 是数组的长度。我们只需要遍历数组一次。
  • 空间复杂度O(1),只使用了常数级别的额外空间。
相关推荐
飞yu流星1 小时前
C++ 函数 模板
开发语言·c++·算法
没有名字的鬼1 小时前
C_字符数组存储汉字字符串及其索引
c语言·开发语言·数据结构
pursuit_csdn1 小时前
力扣 74. 搜索二维矩阵
算法·leetcode·矩阵
labuladuo5201 小时前
洛谷 P8703 [蓝桥杯 2019 国 B] 最优包含(dp)
算法·蓝桥杯·动态规划
Milk夜雨2 小时前
C语言冒泡排序教程简介
数据结构·算法·排序算法
委婉待续2 小时前
redis的学习(三)
数据结构·算法
一直学习永不止步2 小时前
LeetCode题练习与总结:随机翻转矩阵--519
java·数学·算法·leetcode·哈希表·水塘抽样·随机化
xiao--xin2 小时前
LeetCode100之组合总和(39)--Java
java·开发语言·算法·leetcode·回溯
IT猿手4 小时前
部落竞争与成员合作算法(CTCM)求解5个无人机协同路径规划(可以自定义无人机数量及起始点),MATLAB代码
深度学习·算法·机器学习·matlab·无人机·无人机、
GISer_Jing4 小时前
React中 Reconciliation算法详解
前端·算法·react.js