华为算法题:最长连续递增子序列的变

题目描述

给定一个长度为 n 的整数数组 nums,请你找出最长的连续子数组 ,使得该子数组中任意相邻两个元素的差的绝对值恰好为 1。

返回这个最长连续子数组的长度。

注意:子数组是数组中连续的一段,不能排序或改变顺序。

输入描述

  • 第一行:整数 n(1 ≤ n ≤ 10^5)

  • 第二行:n 个整数,表示数组 nums(-10^9 ≤ numsi ≤ 10^9)

输出描述

  • 输出一个整数,表示满足条件的最长连续子数组的长度

示例 1

text

复制代码
输入:
5
1 2 3 5 6

输出:
3

解释:子数组 [1,2,3] 满足相邻差绝对值为1,长度为3。

示例 2

text

复制代码
输入:
6
1 2 3 4 3 2

输出:
4

解释:子数组 [1,2,3,4] 长度为4,或 [4,3,2] 长度为3,最长是4。

示例 3

text

复制代码
输入:
4
5 5 5 5

输出:
1

解释:任意相邻元素差为0,不满足绝对值为1,所以最长长度为1(单个元素视为满足)。

解法思路

核心思想:一次遍历(双指针 / 滑动窗口)

由于要求的是连续子数组,且条件只与相邻元素有关,我们可以用一次线性扫描解决:

  • 维护一个变量 cur 表示以当前位置结尾的最长满足条件的子数组长度。

  • 遍历数组,对于每个位置 i(从1开始):

    • 如果 |nums[i] - nums[i-1]| == 1,则 cur += 1

    • 否则,cur = 1(重新开始)

    • 用 ans 记录 cur 的最大值

时间复杂度 O(n),空间复杂度 O(1)。

为什么不需要滑动窗口?

因为条件只依赖于相邻两个元素,一旦某个相邻对不满足,前面的子数组就无法再延伸,直接重置即可。这类似于求最长连续递增子序列的简化版。

cpp 复制代码
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;

int main() {
    int n;
    cin >> n;
    vector<long long> nums(n);
    for (int i = 0; i < n; i++) cin >> nums[i];
    
    int ans = 1, cur = 1;
    for (int i = 1; i < n; i++) {
        if (abs(nums[i] - nums[i-1]) == 1) {
            cur++;
            ans = max(ans, cur);
        } else {
            cur = 1;
        }
    }
    cout << ans << endl;
    return 0;
}
相关推荐
Rain的Java大神之路1 分钟前
LeetCode 37 解数独面试攻略:回溯 + 位掩码 + MRV,从暴力到毫秒级求解
java·后端·leetcode
NEFU_Jyj7 分钟前
贝尔数(组合数学)
算法
1-1=035 分钟前
C# 数据结构和特殊类型
数据结构·c#·.net·.netcore
希和202743 分钟前
C语言程序设计题|有序数组插入数字冒泡排序
c语言·数据结构·算法
Pniubi1 小时前
力扣73 矩阵置零
算法·leetcode·矩阵
布莱克60511 小时前
C++ 中 map 的 insert 与 emplace:key 已存在时会覆盖吗?
开发语言·数据结构·c++·算法·map
D e re k ZH14 小时前
C++ 系统学习手记:从语法细节到工程实践
开发语言·数据结构·c++·算法
石小石Orz15 小时前
AI 正在蚕食我们的编码能力
前端·后端·算法
民乐团扒谱机16 小时前
【微实验】NSGA-II(非支配排序遗传算法)——解决多目标优化问题的“自然选择模拟器”
linux·人工智能·算法