【题解】力扣978. 最长湍流子数组

题目来源

978. 最长湍流子数组

方法一

滑动窗口,双指针

  • 第一种情况和第二种情况分开讨论
  • 当符合条件的时候,left不动,right加1;
  • 不符合条件的时候,left等于right
  • 窗口长度为right-left+1

长度为1的时候特判,返回1;

代码

class Solution {
    public int maxTurbulenceSize(int[] arr) {
        int n = arr.length;
        int ret = 1;
        int left = 0, right = 0;

        while (right < n - 1) {	// 从0开始,一直到right到n-1为止。
            if (left == right) {	// 这个时候不符合湍流子数组的定义
                if (arr[left] == arr[left + 1]) {	// 如果下一个数字和当前数字相等,滑动窗口直接右移
                    left++;
                }
                right++;
            } else {	// 用right当做下标就不用判断此时是偶数还是奇数
                if (arr[right - 1] < arr[right] && arr[right] > arr[right + 1]) {
                    right++;
                } else if (arr[right - 1] > arr[right] && arr[right] < arr[right + 1]) {
                    right++;
                } else {
                    left = right;
                }
            }
            ret = Math.max(ret, right - left + 1);
        }
        return ret;
    }
}

方法二

动态规划

因为湍流数组为 大 小 大 小.... 或者是 小 大 小 大...的样子。

dp[i][j]i代表数组的下标,j代表当前数字相较于上一个数字是变大还是变小,如果是变小就是0,如果是变大就是1

初始值,只有一个数字的时候,湍流数组为1,dp[0][0] = dp[0][1] = 1;,可以初始化每一个数字的状态都是1,即dp[i][0] = dp[i][1] = 1;

转态转移,每次只要知道上一个数字是变大还是变小,再比较当前位置和上一个位置的数字的大小。如果上一个数字是变大,且当前数字比上一个数字小,即当前数字是变小,符合湍流数组的定义,dp[i][0] = dp[i-1][1]+1。相反的,就是dp[i][1] = dp[i-1][0]+1

代码

class Solution {
    public int maxTurbulenceSize(int[] arr) {
        int n = arr.length;
        int[][] dp = new int[n][2];
        dp[0][0] = dp[0][1] = 1;	// 初始值
        for (int i = 1; i < n; i++) {
            dp[i][0] = dp[i][1] = 1;
            if (arr[i - 1] > arr[i]) {	// 当前状态变小
                dp[i][0] = dp[i - 1][1] + 1;
            } else if (arr[i - 1] < arr[i]) {	// 当前状态变大
                dp[i][1] = dp[i - 1][0] + 1;
            }
        }

        int ret = 1;
        for (int i = 0; i < n; i++) {
            ret = Math.max(ret, dp[i][0]);
            ret = Math.max(ret, dp[i][1]);
        }
        return ret;
    }
}

复杂度分析

  • 时间复杂度为O(n)
  • 空间复杂度为O(n)

因为状态只有1和0,我们可以进行空间优化,将数组变为变量。

class Solution {
    public int maxTurbulenceSize(int[] arr) {
        int len = arr.length;
        if(len == 1) return 1;	// 特判长度为1时的情况(好像不用特判也行)
        int up = 1,down = 1;
        int ans = 1;
        for(int i = 1;i<len;i++){
            if(arr[i] > arr[i-1]){	// 状态变大
                up = down + 1;
                down = 1;	// 记得down要变回1
            }
            else if (arr[i] < arr[i-1]){	// 状态变小
                down = up + 1;
                up = 1;
            }
            else{	// 如果相等,就是湍流数组断了,信息·重新回到1
                up = down = 1;
            }
            // 以下两个if可以用Math.max来代替
            // ans = Math.max(ans, up);
            // ans = Math.max(ans, down);
            if(up > ans){
                ans = up;
            }
            if(down > ans){
                ans = down;
            }
        }
        return ans;
    }
}
posted @ 2021-02-09 22:35  zzzzzy2k  阅读(32)  评论(0编辑  收藏  举报