从何时你也忌讳空山无人,从何时开始|

Drunker•L

园龄:4个月粉丝:0关注:0

978. 最长湍流子数组

最长湍流子数组
给定一个整数数组 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. 子问题重叠(Overlapping Subproblems)

动态规划通常适用于那些可以将大问题分解成相似的子问题的情况。在这道题中,计算当前元素 arr[i] 结尾的最长湍流子数组的长度,依赖于 前一个元素 arr[i-1] 结尾的湍流子数组的长度。也就是说,当前的子问题(在第 i 个位置处的子数组长度)会基于之前的状态(i-1 位置的状态)来递推,形成了子问题的重叠。

2. 状态转移公式(Recurrence Relation)

动态规划通常通过一个明确的状态转移公式来推导出结果。在这道题中,状态 dp1dp2 代表了两个状态:

  • dp1[i] 表示以 arr[i] 结尾且当前元素大于前一个元素(即上升)的最长湍流子数组长度。
  • dp2[i] 表示以 arr[i] 结尾且当前元素小于前一个元素(即下降)的最长湍流子数组长度。

状态转移公式如下:

  • 如果当前元素大于前一个元素(arr[i] > arr[i-1]),则 dp1 = dp2 + 1,表示一个上升趋势。
  • 如果当前元素小于前一个元素(arr[i] < arr[i-1]),则 dp2 = dp1 + 1,表示一个下降趋势。
  • 如果当前元素等于前一个元素,湍流子数组结束,dp1 = dp2 = 1,重置。

3. 最优子结构(Optimal Substructure)

动态规划适用的一个重要条件是问题具有最优子结构。也就是说,整个问题的最优解可以通过子问题的最优解组合而成。在这道题中,以第 i 个位置结尾的最长湍流子数组的长度,依赖于 以第 i-1 个位置结尾的最长湍流子数组的长度。具体地,如果我们知道了前一个位置的子数组信息,就可以决定当前元素是否能继续延伸湍流子数组,并更新最长子数组的长度。

4. 问题的递推性质

  • 由于每个位置的子数组状态只依赖于前一个位置的状态(即 i-1),而每个位置的选择是独立的,因此问题可以通过递推的方式逐步计算出解。我们从左到右处理每个元素,逐步更新 dp1dp2,最后得到结果。
class Solution {
    public int maxTurbulenceSize(int[] arr) {
        int n = arr.length;
        if(n == 1){
            return 1; // 如果数组的长度为1,单个元素就是一个湍流子数组
        }
        // dp1:当前元素以arr[i]结尾,且arr[i] > arr[i-1]的最长湍流子数组
        // dp2:当前元素以arr[i]结尾,且arr[i] < arr[i-1]的最长湍流子数组
        int dp1 = 1, dp2 = 1, maxLength = 1;

        for(int i = 1; i < n; i++){
            if(arr[i] > arr[i-1]){  // 如果当前元素比前一个元素大,表示可能是上升状态
                dp1 = dp2 + 1; // dp1 表示“上升”模式,当前元素扩展了以 arr[i-1] 结尾的下降子数组,因此 dp1 是 dp2 + 1
                dp2 = 1;
            }else if(arr[i] < arr[i-1]){ //如果当前元素比前一个元素小,表示可能是下降状态
                dp2 = dp1 + 1; // dp2 表示“下降”模式,当前元素扩展了以 arr[i-1] 结尾的上升子数组,因此 dp2 是 dp1 + 1
                dp1 = 1;
            }else{
                dp1 = dp2 = 1;
            }
            maxLength = Math.max(maxLength,Math.max(dp1, dp2));
        }
        return maxLength;

    }
}

本文作者:Drunker•L

本文链接:https://www.cnblogs.com/drunkerl/p/18700079

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Drunker•L  阅读(6)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起