文章目录
- Tag
- 题目来源
- 解题思路
- 方法一:枚举
- 方法二:一次遍历
- 其他语言
- python3
- 写在最后
Tag
【一次遍历】【枚举】【数组】【2023-11-16】
题目来源
2760. 最长奇偶子数组
解题思路
方法一:枚举
本题有多种方法可以解决,最朴素的方法就是枚举所有的子数组,对枚举的所有子数组逐一判断是否是符合要求的奇偶数组,统计最大的奇偶数组长度即可。
该方法属于基础语法范畴,不再进行详细分析,具体请见代码。
实现代码
class Solution {public:bool isValid(vector<int>& nums, int l , int r, int threshold) {if (nums[l] % 2 != 0) {return false;}for (int i = l; i <= r; ++i) {if (nums[i] > threshold || (i + 1 <= r && nums[i] % 2 == nums[i+1] % 2)) {return false;}}return true;}int longestAlternatingSubarray(vector<int>& nums, int threshold) {int n = nums.size();int res = 0;for (int l = 0; l < n; ++l) {for (int r = l; r < n; ++r) {if (isValid(nums, l, r, threshold)) {res = max(res, r - l + 1);}}}return res;}};
复杂度分析
时间复杂度: O ( n3)O(n^3)O(n3), nnn 是数组 nums
的长度。
空间复杂度: O ( 1 )O(1)O(1)。
方法二:一次遍历
本方法参考 教你一次性把代码写对!O(n) 分组循环(Python/Java/C++/Go/JS/Rust)。
我们可以先找到有效的开始位置 i
,再从有效的开始位置向后找最长的有效子数组的长度,该方法的时间复杂度为 O ( n )O(n)O(n),因为 i
是一直增加的,不会重置也不会减少。
实现代码
class Solution {public:int longestAlternatingSubarray(vector<int>& nums, int threshold) {int n = nums.size(), res = 0;int i = 0;while (i < n) {if (nums[i] > threshold || nums[i] % 2) {++i;continue;}int start = i;// 子数组的开始++i;// 子数组开始位置已经满足,从下一个位置开始判断while (i < n && nums[i] <= threshold && nums[i] % 2 != nums[i-1] % 2) {++i;}// 从 start 到 i-1 是符合条件的子数组res = max(res, i - start);}return res;}};
以上代码,建议记住,尤其是用 if 来找符合子数组起点,一定会有读者想用 while 来实现,读者可以尝试一下,会遇到很多错误的,如果你最后将 while 语句调试通过了,欢迎评论区沟通交流,你很厉害!
记住的代码可以作为一个模板使用,用来解决 “数组会被分割成若干组,且每一组的判断/处理逻辑是一样的” 这一类问题。
复杂度分析
时间复杂度: O ( n )O(n)O(n)。
空间复杂度: O ( 1 )O(1)O(1)。
其他语言
python3
class Solution:def longestAlternatingSubarray(self, nums: List[int], threshold: int) -> int:n = len(nums)res, i = 0, 0while i threshold or nums[i] % 2:i += 1continuestart = ii += 1while i < n and nums[i] <= threshold and nums[i] % 2 != nums[i-1] % 2:i += 1res = max(res, i - start)return res
写在最后
如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 。
如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。
最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个哦。