|
| 1 | +--- |
| 2 | +title: 2765.最长交替子数组 |
| 3 | +date: 2024-01-23 22:05:37 |
| 4 | +tags: [题解, LeetCode, 简单, 数组, 枚举] |
| 5 | +--- |
| 6 | + |
| 7 | +# 【LetMeFly】2765.最长交替子数组:O(n)的做法(两次遍历) |
| 8 | + |
| 9 | +力扣题目链接:[https://leetcode.cn/problems/longest-alternating-subarray/](https://leetcode.cn/problems/longest-alternating-subarray/) |
| 10 | + |
| 11 | +<p>给你一个下标从 <strong>0</strong> 开始的整数数组 <code>nums</code> 。如果 <code>nums</code> 中长度为 <code>m</code> 的子数组 <code>s</code> 满足以下条件,我们称它是一个 <strong>交替子数组</strong> :</p> |
| 12 | + |
| 13 | +<ul> |
| 14 | + <li><code>m</code> 大于 <code>1</code> 。</li> |
| 15 | + <li><code>s<sub>1</sub> = s<sub>0</sub> + 1</code> 。</li> |
| 16 | + <li>下标从 <strong>0</strong> 开始的子数组 <code>s</code> 与数组 <code>[s<sub>0</sub>, s<sub>1</sub>, s<sub>0</sub>, s<sub>1</sub>,...,s<sub>(m-1) % 2</sub>]</code> 一样。也就是说,<code>s<sub>1</sub> - s<sub>0</sub> = 1</code> ,<code>s<sub>2</sub> - s<sub>1</sub> = -1</code> ,<code>s<sub>3</sub> - s<sub>2</sub> = 1</code> ,<code>s<sub>4</sub> - s<sub>3</sub> = -1</code> ,以此类推,直到 <code>s[m - 1] - s[m - 2] = (-1)<sup>m</sup></code> 。</li> |
| 17 | +</ul> |
| 18 | + |
| 19 | +<p>请你返回 <code>nums</code> 中所有 <strong>交替</strong> 子数组中,最长的长度,如果不存在交替子数组,请你返回 <code>-1</code> 。</p> |
| 20 | + |
| 21 | +<p>子数组是一个数组中一段连续 <strong>非空</strong> 的元素序列。</p> |
| 22 | + |
| 23 | +<p> </p> |
| 24 | + |
| 25 | +<p><strong>示例 1:</strong></p> |
| 26 | + |
| 27 | +<pre> |
| 28 | +<b>输入:</b>nums = [2,3,4,3,4] |
| 29 | +<b>输出:</b>4 |
| 30 | +<b>解释:</b>交替子数组有 [3,4] ,[3,4,3] 和 [3,4,3,4] 。最长的子数组为 [3,4,3,4] ,长度为4 。 |
| 31 | +</pre> |
| 32 | + |
| 33 | +<p><strong>示例 2:</strong></p> |
| 34 | + |
| 35 | +<pre> |
| 36 | +<b>输入:</b>nums = [4,5,6] |
| 37 | +<b>输出:</b>2 |
| 38 | +<strong>解释:</strong>[4,5] 和 [5,6] 是仅有的两个交替子数组。它们长度都为 2 。 |
| 39 | +</pre> |
| 40 | + |
| 41 | +<p> </p> |
| 42 | + |
| 43 | +<p><strong>提示:</strong></p> |
| 44 | + |
| 45 | +<ul> |
| 46 | + <li><code>2 <= nums.length <= 100</code></li> |
| 47 | + <li><code>1 <= nums[i] <= 10<sup>4</sup></code></li> |
| 48 | +</ul> |
| 49 | + |
| 50 | + |
| 51 | +## 方法零:O(n^2)的做法(两层循环) |
| 52 | + |
| 53 | +第一层循环遍历“交替数组”的起点,第二层循环从这个起点开始往后遍历,得到交替数组的终点。更新答案的最大值。 |
| 54 | + |
| 55 | +## 方法一:O(n)的做法(两次遍历) |
| 56 | + |
| 57 | +对于样例```[2, 3, 4, 3, 4]```,我们不能将```3```分给```2 3```,而是要把```3```分给```3 4 3 4```。 |
| 58 | + |
| 59 | +怎么办呢?其实“交替数组”一共有两种:从奇数下标开始的数组和从偶数下标开始的数组。 |
| 60 | + |
| 61 | +因此,我们写一个函数来求“交替数组”,参数为“奇数下标时下一个元素该加一还是减一”。 |
| 62 | + |
| 63 | +求完两种交替数组的最大值,取二者最大的那个即为答案。 |
| 64 | + |
| 65 | ++ 时间复杂度$O(n)$,其中$n=len(nums)$ |
| 66 | ++ 空间复杂度$O(1)$ |
| 67 | + |
| 68 | +### AC代码 |
| 69 | + |
| 70 | +#### C++ |
| 71 | + |
| 72 | +```cpp |
| 73 | +class Solution { |
| 74 | +private: |
| 75 | + int get1(vector<int>& nums, int oddLoc=1) { |
| 76 | + int evenLoc = -oddLoc; |
| 77 | + int ans = 1; |
| 78 | + int cnt = 1; |
| 79 | + for (int i = 0; i < nums.size(); i++) { |
| 80 | + int shouldAdd = i % 2 ? oddLoc : evenLoc; |
| 81 | + if (i + 1 == nums.size() || nums[i + 1] != nums[i] + shouldAdd || cnt == 1 && shouldAdd == -1) { |
| 82 | + ans = max(ans, cnt); |
| 83 | + cnt = 1; |
| 84 | + } |
| 85 | + else { |
| 86 | + cnt++; |
| 87 | + } |
| 88 | + } |
| 89 | + return ans; |
| 90 | + } |
| 91 | +public: |
| 92 | + int alternatingSubarray(vector<int>& nums) { |
| 93 | + int ans = max(get1(nums), get1(nums, -1)); |
| 94 | + return ans < 2 ? -1 : ans; |
| 95 | + } |
| 96 | +}; |
| 97 | +``` |
| 98 | +
|
| 99 | +#### Python |
| 100 | +
|
| 101 | +```python |
| 102 | +# from typing import List |
| 103 | +
|
| 104 | +class Solution: |
| 105 | + def get1(self, oddLoc=1) -> int: |
| 106 | + evenLoc = -oddLoc |
| 107 | + ans = 1 |
| 108 | + cnt = 1 |
| 109 | + for i in range(len(self.nums)): |
| 110 | + shouldAdd = oddLoc if i % 2 else evenLoc |
| 111 | + if i + 1 == len(self.nums) or self.nums[i + 1] != self.nums[i] + shouldAdd or (cnt == 1 and shouldAdd == -1): |
| 112 | + ans = max(ans, cnt) |
| 113 | + cnt = 1 |
| 114 | + else: |
| 115 | + cnt += 1 |
| 116 | + return ans |
| 117 | +
|
| 118 | + def alternatingSubarray(self, nums: List[int]) -> int: |
| 119 | + self.nums = nums |
| 120 | + ans = max(self.get1(), self.get1(-1)) |
| 121 | + return ans if ans >= 2 else -1 |
| 122 | +``` |
| 123 | + |
| 124 | +> 同步发文于CSDN,原创不易,转载经作者同意后请附上[原文链接](https://blog.tisfy.eu.org/2024/01/23/LeetCode%202765.%E6%9C%80%E9%95%BF%E4%BA%A4%E6%9B%BF%E5%AD%90%E6%95%B0%E7%BB%84/)哦~ |
| 125 | +> Tisfy:[https://letmefly.blog.csdn.net/article/details/135794883](https://letmefly.blog.csdn.net/article/details/135794883) |
0 commit comments