Day01 线性枚举_1

109 阅读6分钟

1550. 存在连续三个奇数的数组

给你一个整数数组 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

Code

我的题解

class Solution {
public:
    bool threeConsecutiveOdds(vector<int>& arr) {
        if (arr.size() < 3) {
            return false;
        }
        for (int i = 0; i < arr.size() - 2; ++i) {
            if (arr[i] % 2 == 1 && arr[i+1] % 2 == 1 && arr[i+2] % 2 == 1) {
                return true;
            }
        }
        return false;
    }
};

力扣官方题解

class Solution {
public:
    bool threeConsecutiveOdds(vector<int>& arr) {
        // 获取数组的长度,并存储在变量n中
        int n = arr.size();
        
        // 遍历数组,直到倒数第三个元素
        // 因为我们需要检查连续的三个元素,所以循环到倒数第三个元素就足够了
        for (int i = 0; i <= n - 3; ++i) {
            // 使用位运算符 '&' 来检查连续的三个元素是否都是奇数
            // arr[i] & 1 的结果是:
            // 如果 arr[i] 是奇数,结果是 1(因为奇数的最低位是1)
            // 如果 arr[i] 是偶数,结果是 0(因为偶数的最低位是0)
            // 重复这个操作对 arr[i + 1] 和 arr[i + 2] 进行检查
            if ((arr[i] & 1) & (arr[i + 1] & 1) & (arr[i + 2] & 1)) {
                // 如果这三个连续的元素都是奇数,那么返回true
                return true;
            }
        }
        // 如果循环结束后没有找到连续的三个奇数,那么返回false
        return false;
    }
};

这段代码定义了一个名为 Solution 的类,其中包含一个公共成员函数 threeConsecutiveOdds。这个函数接受一个整数类型的向量 arr 作为参数,并返回一个布尔值。

在 C++ 中,vector<int>& arr 是一个函数参数声明,它具有以下几个组成部分:

  1. vector<int>:这表示一个模板类 vector 的实例,用于存储 int 类型的元素。std::vector 是 C++ 标准库中的一个动态数组,可以存储任意数量的元素,并且在运行时可以改变大小。在这里,vector<int> 表示一个整数数组。

  2. &:这个符号表示引用。在 C++ 中,引用是一个变量的别名。当你将一个变量通过引用传递给函数时,你实际上是传递了这个变量的引用,而不是它的拷贝。这意味着在函数内部对引用的任何操作都会影响到原始变量。

  3. arr:这是参数的名称,在函数体内部用于引用传递进来的 vector<int> 实例。

vector<int>& arr 作为函数参数的好处:

  • 避免复制:如果你没有使用引用,那么传递给函数的 vector 会被复制一份,这可能会涉及大量的数据复制,导致不必要的性能开销。通过使用引用,你可以避免复制整个数组,只传递一个指向原始数组的引用。
  • 允许修改:通过引用传递 vector,函数可以直接修改原始数组。如果你不希望函数修改原始数组,可以使用 const 关键字,即 const vector<int>& arr,这样函数内部就不能修改数组的内容。这样,你既保证了效率(因为没有发生复制),又保护了数据(因为 arr 是只读的)。

在你提供的代码上下文中,vector<int>& arr 表示函数 threeConsecutiveOdds 接收一个整数向量的引用作为参数,并且此函数可以直接在原始向量上进行操作,而无需复制整个向量。


函数的目标是检查 arr 中是否存在三个连续的奇数。为了实现这一点,它首先获取数组的长度 n。然后,它通过一个 for 循环遍历数组,直到倒数第三个元素。在每次迭代中,它使用位运算符 & 来检查 arr[i]arr[i + 1]arr[i + 2] 这三个连续元素是否都是奇数。位运算 & 1 会检查整数的最低位是否为1,这是奇数的特征。如果所有三个元素的最低位都是1,那么这三个数都是奇数,函数返回 true。如果循环完成后没有找到这样的三个连续奇数,函数返回 false

这个函数的时间复杂度是 O(n),其中 n 是数组 arr 的长度,因为它需要遍历数组中的每个元素。空间复杂度是 O(1),因为它只使用了固定的额外空间(即变量 n 和循环索引 i)。

英雄哪里出来

class Solution {
public:
    bool threeConsecutiveOdds(vector<int>& arr) {
        for (int i = 0; i + 2 < arr.size(); ++i) {
            int a = arr[i];
            int b = arr[i+1];
            int c = arr[i+2];
            if ( a%2 && b%2 && c%2 ) {
                return true;
            }
        }
        return false;
    }
};

补全完整可运行代码

这代码没有main函数耶,在实际中是怎么调用的呢?你能尝试补全一份完整的代码吗?


在实际的应用程序中,main 函数是程序的入口点,它负责调用其他函数和类以执行程序的逻辑。对于类似上面的 Solution 类,通常会在 main 函数中创建一个 Solution 对象,并使用该对象调用成员函数。

以下是一个包含 main 函数的完整示例,它创建了一个 Solution 对象,并使用它来检查一个数组中是否存在连续三个奇数的情况:

#include <iostream>
#include <vector>

class Solution {
public:
    bool threeConsecutiveOdds(std::vector<int>& arr) {
        int n = arr.size();
        for (int i = 0; i <= n - 3; ++i) {
            if ((arr[i] & 1) && (arr[i + 1] & 1) && (arr[i + 2] & 1)) {
                return true;
            }
        }
        return false;
    }
};

int main() {
    // 创建一个 Solution 对象
    Solution solution;

    // 定义几个测试数组
    std::vector<int> arr1 = {2, 6, 4, 1};
    std::vector<int> arr2 = {1, 2, 34, 3, 4, 5, 7, 23, 12};

    // 调用函数并输出结果
    bool result1 = solution.threeConsecutiveOdds(arr1);
    std::cout << "Does arr1 contain three consecutive odds? " << (result1 ? "Yes" : "No") << std::endl;

    bool result2 = solution.threeConsecutiveOdds(arr2);
    std::cout << "Does arr2 contain three consecutive odds? " << (result2 ? "Yes" : "No") << std::endl;

    return 0;
}

在这个示例中,我们定义了两个测试用例 arr1arr2,并分别调用 threeConsecutiveOdds 函数来检查它们。我们使用标准输出(std::cout)来显示结果。在实际的程序中,你可能会根据需要进行更复杂的逻辑处理,但这个示例展示了如何在 main 函数中使用 Solution 类。


#include <iostream>
#include <sstream>
#include <vector>
#include <string>

class Solution {
public:
    bool threeConsecutiveOdds(std::vector<int>& arr) {
        int n = arr.size();
        for (int i = 0; i <= n - 3; ++i) {
            if ((arr[i] & 1) && (arr[i + 1] & 1) && (arr[i + 2] & 1)) {
                return true;
            }
        }
        return false;
    }
};

int main() {
    Solution solution;
    std::string line;

    // 读取两行输入
    for (int i = 1; i <= 2; ++i) {
        std::getline(std::cin, line); // 读取一整行
        std::istringstream iss(line);
        std::vector<int> arr;
        int num;
        while (iss >> num) { // 从字符串流中读取整数
            arr.push_back(num);
        }

        // 调用函数并输出结果
        bool result = solution.threeConsecutiveOdds(arr);
        std::cout << (result ? "true" : "false") << std::endl;
    }

    return 0;
}

这段代码使用 std::getline 来读取一整行输入,然后使用 std::istringstream 将这行输入转换成一个字符串流,接着通过字符串流读取每个整数并存入数组。程序会分别对两行输入进行处理,并输出每个数组是否存在三个连续的奇数。