青训营X豆包MarsCode 技术训练营刷题-完美偶数计数 | 豆包MarsCode AI 刷题

50 阅读4分钟

完美偶数计数

问题描述

小C定义了一个“完美偶数”。一个正整数 xxx 被认为是完美偶数需要满足以下两个条件:

  • xxx 是偶数;
  • xxx 的值在区间 [l,r][l, r][l,r] 之间。

现在,小C有一个长度为 nnn 的数组 aaa,她想知道在这个数组中有多少个完美偶数。

测试用例

测试用例 1
less
复制代码
输入: n=5, l=3, r=8, a=[1, 2, 6, 8, 7]
输出: 2
测试用例 2
less
复制代码
输入: n=4, l=10, r=20, a=[12, 15, 18, 9]
输出: 2
测试用例 3
less
复制代码
输入: n=3, l=1, r=10, a=[2, 4, 6]
输出: 3

问题求解思路

本题的关键在于遍历数组,检查每个元素是否符合两个条件:

  1. 是否是偶数。
  2. 是否位于给定区间 [l,r][l, r][l,r] 内。

可以逐个检查数组中的元素,如果满足这两个条件,就计数增加。

代码实现

cpp
复制代码
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int solution(int n, int l, int r, vector<int>& a) {
    int tem = 0;
    for(int i = 0; i < n; i++) {
        if(a[i] >= l && a[i] <= r && a[i] % 2 == 0) {
            tem++;
        }
    }
    return tem;
}

int main() {
    vector<int> a1 = {1, 2, 6, 8, 7};
    cout << (solution(5, 3, 8, a1) == 2) << endl;

    vector<int> a2 = {12, 15, 18, 9};
    cout << (solution(4, 10, 20, a2) == 2) << endl;

    vector<int> a3 = {2, 4, 6};
    cout << (solution(3, 1, 10, a3) == 3) << endl;
}

代码解读

1. 函数定义

solution 函数接收四个参数:n 表示数组的大小,lr 定义了区间,a 是输入的数组。

2. 遍历数组

我们使用 for 循环遍历数组中的每个元素,对于每个元素 a[i]

  • 首先检查是否在区间 [l,r][l, r][l,r] 内;
  • 然后检查该数字是否为偶数(即 a[i] % 2 == 0)。

如果这两个条件都满足,就将计数器 tem 加 1。

3. 主函数

主函数中对三个测试用例进行了调用,并通过 cout 输出是否结果正确。

复杂度分析

时间复杂度

  • 我们对数组 aaa 中的每个元素都进行了检查。假设数组大小为 nnn,那么时间复杂度是 O(n)O(n)O(n),因为我们需要遍历每个元素并对其进行两次常数时间的判断。

空间复杂度

  • 由于我们只使用了常数空间来存储计数器 tem 和一些循环变量,因此空间复杂度为 O(1)O(1)O(1),即常数空间。

优化思考

该问题本身的复杂度已经非常低,时间复杂度为 O(n)O(n)O(n),这已经是最优解。然而,我们可以思考在实际应用中是否有进一步的优化空间:

  • 如果我们提前对输入数组进行了某种预处理,比如按照数值的大小进行排序,可能在某些场景下能减少无效的判断操作。但对于本问题而言,直接逐一检查每个元素已经是非常高效的方法。
  • 另外,我们可以考虑对于非常大的数组,是否采用并行计算的方式来提升性能,尤其是在分布式系统或多核处理器的环境下。

总结

通过本题的解决,我们不仅加深了对条件判断和数组遍历的理解,还思考了如何优化基本的算法结构。尽管在本题中最直接的解决方式已经足够高效,但我们可以继续思考如何在不同规模的输入下优化时间和空间的使用。此外,这类问题也让我们意识到对数据区间和属性(如偶数、奇数)的判断可以通过简单的算术操作来快速实现。

希望通过这个简单的问题分析和代码实现,大家能更加熟悉如何高效地解决类似的编程问题,并掌握基本的算法技巧。在未来的学习中,我们还可以通过算法优化和数据结构的改进,进一步提高我们的编程能力。