📜  门| GATE-CS-2016(套装1)|第 56 题(1)

📅  最后修改于: 2023-12-03 15:28:44.888000             🧑  作者: Mango

题目描述

给定一个由正整数组成的数组,找到数组中满足以下条件的连续子数组的最大值:

  • 子数组的和是奇数。

  • 子数组的长度是偶数。

函数签名
def max_odd_even_subarray(arr: List[int]) -> int:
    pass
输入
  • arr:由正整数组成的数组,$1 \leq len(arr) \leq 10^5$,$1 \leq arr_i \leq 10^9$。
输出

返回满足条件的最大子数组的和。

样例
assert max_odd_even_subarray([1, 2, 3, 4]) == 6
assert max_odd_even_subarray([13, 1, 2, 4, 6]) == 30
解题思路

这道题可以使用一个类似滑动窗口的算法,从左到右遍历数组,维护左端点 $i$ 和右端点 $j$,不停地计算 $i, j$ 对应的子数组的和,直到找到符合条件的最大子数组为止。

具体来讲,每次右端点 $j$ 向右移动一位,如果当前子数组的长度 $(j-i+1)$ 是奇数,就累加这个子数组的和;如果当前子数组的长度是偶数,就把 $i$ 右移一位,因为无论加上还是减去 arr[i],子数组的和都不会改变。

需要注意的是,我们需要用一个变量 $ans$ 来保存符合条件的最大子数组的和,因为我们可能会遍历整个数组,依然没有找到符合条件的最大子数组。

代码实现
from typing import List


def max_odd_even_subarray(arr: List[int]) -> int:
    i, sum_of_subarray, ans = 0, 0, 0
    for j in range(len(arr)):
        sum_of_subarray += arr[j]
        if (j-i+1) % 2 == 0:
            if sum_of_subarray % 2 == 1:
                ans = max(ans, sum_of_subarray)
            sum_of_subarray -= arr[i]
            i += 1
        elif j == len(arr) - 1:
            if sum_of_subarray % 2 == 1:
                ans = max(ans, sum_of_subarray)
    return ans
复杂度分析
  • 时间复杂度:$O(n)$,因为数组只会遍历一遍。

  • 空间复杂度:$O(1)$,因为我们只需要用常数个变量来保存数据。