leetcode
leetcode 2351 ~ 2400
最长交替子数组

最长交替子数组

难度:

标签:

题目描述

You are given a 0-indexed integer array nums. A subarray s of length m is called alternating if:

  • m is greater than 1.
  • s1 = s0 + 1.
  • The 0-indexed subarray s looks like [s0, s1, s0, s1,...,s(m-1) % 2]. In other words, s1 - s0 = 1, s2 - s1 = -1, s3 - s2 = 1, s4 - s3 = -1, and so on up to s[m - 1] - s[m - 2] = (-1)m.

Return the maximum length of all alternating subarrays present in nums or -1 if no such subarray exists.

A subarray is a contiguous non-empty sequence of elements within an array.

 

Example 1:

Input: nums = [2,3,4,3,4]
Output: 4
Explanation: The alternating subarrays are [3,4], [3,4,3], and [3,4,3,4]. The longest of these is [3,4,3,4], which is of length 4.

Example 2:

Input: nums = [4,5,6]
Output: 2
Explanation: [4,5] and [5,6] are the only two alternating subarrays. They are both of length 2.

 

Constraints:

  • 2 <= nums.length <= 100
  • 1 <= nums[i] <= 104

代码结果

运行时间: 22 ms, 内存: 16.1 MB


/*
思路:
1. 使用Java Stream API遍历数组,检查每个长度大于1的子数组是否为交替子数组。
2. 如果当前子数组满足交替子数组的条件,则更新最长交替子数组的长度。
3. 返回最长的交替子数组的长度,如果不存在则返回-1。
*/

import java.util.stream.IntStream;

public class Solution {
    public int longestAlternatingSubarray(int[] nums) {
        return IntStream.range(0, nums.length - 1)
                .map(i -> {
                    int length = 1;
                    boolean isAlternating = true;
                    for (int j = i; j < nums.length - 1; j++) {
                        if ((j - i) % 2 == 0 && nums[j + 1] != nums[j] + 1) {
                            isAlternating = false;
                            break;
                        }
                        if ((j - i) % 2 == 1 && nums[j + 1] != nums[j] - 1) {
                            isAlternating = false;
                            break;
                        }
                        length++;
                    }
                    return isAlternating && length > 1 ? length : -1;
                })
                .max()
                .orElse(-1);
    }
}

解释

方法:

该题解采用双指针策略来检测并统计最长的交替子数组。首先初始化两个指针a和b,分别代表交替子数组的当前两个连续元素。变量cnt用于记录当前交替子数组的长度,而max_cnt用于记录遇到的最长交替子数组的长度。接下来,遍历数组中的每个元素,检查当前元素是否能延续当前的交替模式。如果可以,则更新a,b和cnt。如果不可以,就将当前的cnt与max_cnt比较,更新max_cnt,并尝试重新开始一个新的交替子数组。循环结束后,再次比较cnt和max_cnt确保最后一个可能的子数组被正确处理。如果max_cnt仍为0,说明没有找到合适的交替子数组,返回-1。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
在双指针策略中,a和b指针的具体作用是什么?它们是如何帮助识别和扩展交替子数组的?
在双指针策略中,a和b作为指针主要用于追踪交替子数组中的最后两个元素。它们帮助确定当前数组元素是否与前一个元素交替(即符合交替模式的递增或递减关系)。当当前元素符合与前一个元素的交替模式时,指针a和b的值会更新,以此延续并记录当前的交替子数组。如果当前元素不符合交替模式,指针a和b则会重置,以尝试在新的位置开始识别新的交替子数组。
🦆
题解中提到如果当前元素x能继续交替模式,则会更新a和b的值。请问在什么情况下x被认为是能继续当前的交替模式?
在题解中,当前元素x被认为可以继续交替模式的条件是x等于前一个元素a。这意味着x能够与前一个元素a形成有效的交替关系(例如,如果前一个元素是递增的下一个元素,则当前元素应为递增后的值),从而可以继续当前的交替子数组。当这种情况发生时,a和b的值会更新,其中a变为b,b变为x,以此继续扩展交替子数组的长度。
🦆
当检测到当前元素x不能继续交替模式时,代码进行了哪些操作来尝试重新开始一个新的交替子数组?这种方法是否能够确保不遗漏任何可能的交替子数组?
当当前元素x不能继续交替模式时,代码首先会比较并更新max_cnt,以记录到目前为止找到的最长交替子数组的长度。然后,a和b的值会更新为最近的b和当前的x,尝试重新开始一个新的交替子数组。同时,cnt会重置为2(如果b和x满足交替条件),表示新子数组的初始长度。这种方法在每次发现当前元素无法继续交替子数组时重新开始计数,并更新最大长度,可以有效确保不遗漏任何可能的交替子数组。
🦆
如果数组中的数字都是相同的,例如nums = [5, 5, 5, 5],该算法会返回什么结果?算法对这种情况的处理是否合理?
当数组中的数字都相同时,例如nums = [5, 5, 5, 5],算法会返回-1。这是因为所有元素都相同,无法形成任何交替模式。算法在这种情况下的处理是合理的,因为交替子数组的定义要求元素之间必须交替(即有递增或递减的关系),相同的元素之间无法形成这种关系。

相关问题