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

题目描述

给定一个长度为 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;
}
相关推荐
YOLO数据集集合1 小时前
机器学习二分类预测算法组合工具:12种算法、113种组合的批量建模方案8031期
算法·机器学习
longlongzihan1 小时前
LeetCode 56合并区间:排序与贪心
c++·算法·leetcode
w_zero_one2 小时前
链表(2)
java·数据结构·链表
学术小李2 小时前
cudaMalloc第一个参数为何是指针的指针
算法
kukubuzai2 小时前
二分查找系列一
数据结构·算法·leetcode
老歌老听老掉牙2 小时前
动态规划:从递归到最优决策的算法艺术
算法·动态规划
朔北之忘 Clancy2 小时前
2024 CSP-J 第二轮真题解析
c++·算法·青少年编程·noip·csp·信奥赛·noi
小七在进步2 小时前
类和对象(五)
java·开发语言·算法