Leetcode刷题详解——最长湍流子数组

文章介绍了如何使用动态规划解决给定整数数组找到最长湍流子数组的问题,通过状态表示、转移方程和C++代码实现算法,最终返回最长湍流子数组的长度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 题目链接:978. 最长湍流子数组

2. 题目描述:

给定一个整数数组 arr ,返回 arr最大湍流子数组的长度

如果比较符号在子数组中的每个相邻元素对之间翻转,则该子数组是 湍流子数组

更正式地来说,当 arr 的子数组 A[i], A[i+1], ..., A[j] 满足仅满足下列条件时,我们称其为湍流子数组

  • i <= k < j
    

    • k 为奇数时, A[k] > A[k+1],且
    • k 为偶数时,A[k] < A[k+1]
  • i <= k < j
    

    • k 为偶数时,A[k] > A[k+1] ,且
    • k 为奇数时, A[k] < A[k+1]

示例 1:

输入:arr = [9,4,2,10,7,8,8,1,9]
输出:5
解释:arr[1] > arr[2] < arr[3] > arr[4] < arr[5]

示例 2:

输入:arr = [4,8,12,16]
输出:2

示例 3:

输入:arr = [100]
输出:1

提示:

  • 1 <= arr.length <= 4 * 104
  • 0 <= arr[i] <= 109

3. 解法(动态规划):

3.1 算法思路:

1. 状态表示:

f[i]表示:以i位置元素为结尾的所有子数组中,最后呈现上升状态下的最长湍流数组的长度

g[i]表示:以i位置元素为结尾的所有子数组中,最后呈现下降状态下的最长湍流数组的长度

2. 状态转移方程:

对于i位置的元素 arr[i],又下面两种情况:

  1. arr[i]>arr[i-1]:如果i位置的元素比 i-1位置的元素大,说明接下来应该去找 i-1位置结尾,并且 i-1位置元素比前面一个元素小的序列,那就是 g[i-1],更新 f[i]位置的值:f[i]=g[i-1]+1
  2. arr[i]<arr[i-1]:如果i位置的元素比 i-1位置元素小,说明接下来应该找 i-1位置结尾,并且 i-1位置元素比前一个元素大的序列,那就是 f[i-1]。更新 g[i]位置的值:g[i]=f[i-1]+1
  3. arr[i]=arr[i-1]:不构成湍流数组

请添加图片描述

3. 初始化:

所有的元素单独都能构成一个湍流数组,因此可以将 dp表内所有元素初始化为1

由于用到前面的状态,因此我们循环的时候从第二个位置开始即可

4. 填表顺序:

从左往右,两个表一起填

5. 返回值:

返回两个dp表里面的最大值,我们可以在填表的时候,顺序更新一些最大值

3.2 C++算法代码:

class Solution {
public:
    // 计算数组中最大的湍流子数组的长度
    int maxTurbulenceSize(vector<int>& arr) {
        int n = arr.size(); // 获取数组长度
        vector<int> f(n, 1), g(n, 1); // 初始化两个辅助数组f和g,初始值都为1
        int ret = 1; // 初始化最大湍流子数组长度为1
        for (int i = 1; i < n; i++) {
            // 如果当前元素大于前一个元素,更新f[i]
            if (arr[i - 1] < arr[i]) {
                f[i] = g[i - 1] + 1;
            }
            // 如果当前元素小于前一个元素,更新g[i]
            else if (arr[i - 1] > arr[i]) {
                g[i] = f[i - 1] + 1;
            }
            // 如果当前元素等于前一个元素,重置f[i]和g[i]为1
            ret = max(ret, max(f[i], g[i])); // 更新最大湍流子数组长度
        }
        return ret; // 返回最大湍流子数组长度
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值