存在连续三个奇数的数组

标签: 数组

难度: Easy

给你一个整数数组 arr,请你判断数组中是否存在连续三个元素都是奇数的情况:如果存在,请返回 true ;否则,返回 false

示例 1:

输入:arr = [2,6,4,1]
输出:false
解释:不存在连续三个元素都是奇数的情况。

示例 2:

输入:arr = [1,2,34,3,4,5,7,23,12]
输出:true
解释:存在连续三个元素都是奇数的情况,即 [5,7,23] 。

提示:

  • 1 <= arr.length <= 1000
  • 1 <= arr[i] <= 1000

Submission

运行时间: 17 ms

内存: 15.9 MB

class Solution:
    def threeConsecutiveOdds(self, arr: List[int]) -> bool:
        n = len(arr)
        return n >= 3 and \
            any(arr[i] & 1 and arr[i + 1] & 1 and arr[i + 2] & 1 \
                for i in range(n - 2))

Explain

此题解采用直接的遍历方法来检查数组中是否存在连续三个奇数。首先,通过长度检验确保数组至少包含三个元素。接着,使用一个循环遍历数组元素,并通过位运算 `& 1` 检查每个元素是否为奇数(如果一个数与 1 进行位与运算结果为 1,则该数是奇数)。循环中检查每个元素及其后两个元素是否都是奇数。若找到这样的连续三个奇数,则立即返回 `true`。如果遍历完成后没有找到,则返回 `false`。

时间复杂度: O(n)

空间复杂度: O(1)

class Solution:
    def threeConsecutiveOdds(self, arr: List[int]) -> bool:
        n = len(arr)  # 获取数组长度
        # 检查数组长度至少为3并且存在连续三个奇数的情况
        return n >= 3 and any(arr[i] & 1 and arr[i + 1] & 1 and arr[i + 2] & 1 for i in range(n - 2))

Explore

这一步骤是出于效率和防止错误的考虑。如果数组长度小于3,那么数组中不可能存在连续三个奇数,因此这种情况下直接返回false可以避免不必要的计算。此外,如果不先进行长度检查,后续的循环中尝试访问 `arr[i+1]` 和 `arr[i+2]` 可能会导致越界错误。

位运算 `& 1` 被用来检查一个数的最低位是否为1,这是判断一个数是否为奇数的快速方法。其他方法包括使用模运算 `num % 2 != 0` 来判断奇数。虽然模运算同样可以达到目的,但位运算通常会更快,因为它只涉及二进制的直接操作,而不涉及除法运算,从而提高了效率。

在这个特定场景中,使用 `any` 函数结合生成器表达式可以提供更高的效率和可读性。`any` 函数会在找到第一个符合条件的结果时立即停止检查,这是一种短路行为,可以节省不必要的计算。与直接使用三重循环(可能需要检查每种组合,即使已经找到符合条件的组合)相比,这种方法更为高效。

如果数组中所有的数都是奇数,那么题解的方法将在最开始的几次检查后就能找到符合条件的连续三个奇数。具体来说,如果数组的前三个数都是奇数,那么程序将在第一次检查时就返回 `true`,从而避免了对整个数组的完全遍历。这表明该方法在这种极端情况下的表现非常好,能够迅速得出结论。