[LeetCode] 978. Longest Turbulent Subarray

Given an integer array arr, return the length of a maximum size turbulent subarray of arr.

A subarray is turbulent if the comparison sign flips between each adjacent pair of elements in the subarray.

More formally, a subarray [arr[i], arr[i + 1], ..., arr[j]] of arr is said to be turbulent if and only if:

  • For i <= k < j:
    • arr[k] > arr[k + 1] when k is odd, and
    • arr[k] < arr[k + 1] when k is even.
  • Or, for i <= k < j:
    • arr[k] > arr[k + 1] when k is even, and
    • arr[k] < arr[k + 1] when k is odd.

Example 1:

Input: arr = [9,4,2,10,7,8,8,1,9]
Output: 5
Explanation: arr[1] > arr[2] < arr[3] > arr[4] < arr[5]

Example 2:

Input: arr = [4,8,12,16]
Output: 2

Example 3:

Input: arr = [100]
Output: 1

Constraints:

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

最长湍流子数组。

当 A 的子数组 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]。
也就是说,如果比较符号在子数组中的每个相邻元素对之间翻转,则该子数组是湍流子数组。

返回 A 的最大湍流子数组的长度。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-turbulent-subarray
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路是类似53题的动态规划。湍流子数组的定义是比较符号在相邻元素对之间翻转,那么我们可以定义两个数组 int[] increase 和 int[] decrease,都是以 nums[i] 为结尾的,最后一位是上升/下降的子数组。接下来分如下几种情况

  • 如果nums[i] > nums[i - 1],说明最后一段是上升的,以他为结尾的子数组的最大长度 = 前一段是下降的子数组的最大长度 + 1
  • 如果nums[i] < nums[i - 1],说明最后一段是下降的,以他为结尾的子数组的最大长度 = 前一段是上升的子数组的最大长度 + 1
  • 如果nums[i] = nums[i - 1],说明最后一段是平行的,以他为结尾的子数组的最大长度只能是1

时间O(n)

空间O(n)

Java实现

 1 class Solution {
 2     public int maxTurbulenceSize(int[] A) {
 3         int len = A.length;
 4         // corner case
 5         if (len < 2) {
 6             return len;
 7         }
 8 
 9         // normal case
10         // 以 arr[i] 结尾,并且 arr[i - 1] < arr[i] 的湍流子数组的长度
11         int[] increased = new int[len];
12         // 以 arr[i] 结尾,并且 arr[i - 1] > arr[i] 的湍流子数组的长度
13         int[] decreased = new int[len];
14         increased[0] = 1;
15         decreased[0] = 1;
16         int res = 1;
17         for (int i = 1; i < len; i++) {
18             if (A[i - 1] < A[i]) {
19                 increased[i] = decreased[i - 1] + 1;
20                 decreased[i] = 1;
21             } else if (A[i - 1] > A[i]) {
22                 increased[i] = 1;
23                 decreased[i] = increased[i - 1] + 1;
24             } else {
25                 increased[i] = 1;
26                 decreased[i] = 1;
27             }
28             res = Math.max(res, Math.max(increased[i], decreased[i]));
29         }
30         return res;
31     }
32 }

跟53题类似,这里我提供一个不用额外空间的做法。

时间O(n)

空间O(n)

Java实现

 1 class Solution {
 2     public int maxTurbulenceSize(int[] A) {
 3         int len = A.length;
 4         // corner case
 5         if (len < 2) {
 6             return len;
 7         }
 8 
 9         // normal case
10         int increase = 1;
11         int decrease = 1;
12         int res = 1;
13         for (int i = 1; i < A.length; i++) {
14             if (A[i - 1] < A[i]) {
15                 increase = decrease + 1;
16                 decrease = 1;
17             } else if (A[i - 1] > A[i]) {
18                 decrease = increase + 1;
19                 increase = 1;
20             } else {
21                 increase = 1;
22                 decrease = 1;
23             }
24             res = Math.max(res, Math.max(increase, decrease));
25         }
26         return res;
27     }
28 }

相关题目

53. Maximum Subarray

152. Maximum Product Subarray

918. Maximum Sum Circular Subarray

978. Longest Turbulent Subarray

LeetCode 题目总结

原文地址:https://www.cnblogs.com/cnoodle/p/14401448.html