数组分组求偶数和 | 豆包MarsCode AI刷题

137 阅读4分钟

题目链接

数字分组求偶数和 - MarsCode

题目描述

问题描述

小M面对一组从 1 到 9 的数字,这些数字被分成多个小组,并从每个小组中选择一个数字组成一个新的数。目标是使得这个新数的各位数字之和为偶数。任务是计算出有多少种不同的分组和选择方法可以达到这一目标。

  • numbers: 一个由多个整数字符串组成的列表,每个字符串可以视为一个数字组。小M需要从每个数字组中选择一个数字。

例如对于[123, 456, 789],14个符合条件的数为:147 149 158 167 169 248 257 259 268 347 349 358 367 369


测试样例

样例1:

输入:numbers = [123, 456, 789] 输出:14

样例2:

输入:numbers = [123456789] 输出:4

样例3:

输入:numbers = [14329, 7568] 输出:10

题目思路

  1. 遍历每个数字组: 对于每个数字组,分析其中的数字是奇数还是偶数。

  2. 计算选择方式:

    • 记录每个组中奇数和偶数的数量。
    • 组合选择时,确保最终数字的和为偶数。
  3. 动态规划或组合计算: 利用组合数学的原理来计算有效组合的总数。

关键步骤

  • 统计每个组中奇数和偶数的数量。
  • 根据组合的奇偶性,计算所有可能的组合方式,使得最终数字和为偶数。

复杂度

  • 时间复杂度主要取决于数字组的数量和每个组内数字的个数,通常为 O(n * m),其中 n 是数字组的数量,m 是每组的平均数字个数。

存储每种选择的组合数

long long evenCount = 1; // 记录偶数选择的组合数  
// 偶数可以什么都不选,所以初始化为1
long long oddCount = 0;  // 记录奇数选择的组合数  
// 遍历数组中的每个数字
    for(auto i:numbers) {
        long long even = 0, odd = 0;  // 记录当前数字的偶数和奇数的个数
        while(i){
            int j = i % 10;
            i /= 10;
            if(j % 2 == 0) even++;
            else odd++;
        }
        // 处理完毕后,我们更新选择的组合数
        long long NewevenCount = evenCount * even + oddCount * odd;
        long long NewoddCount = oddCount * even + evenCount * odd;
        evenCount = NewevenCount;
        oddCount = NewoddCount;
    }
    return evenCount;

我们遍历数组,取出每个数字,算出这个数字的奇数和偶数的数目,然后计算出一共有多少种组合方式

最后输出

题解代码

#include <iostream>
#include <vector>long long solution(std::vector<int> numbers) {
    long long evenCount = 1; // 记录偶数选择的组合数  
    // 偶数可以什么都不选,所以初始化为1
    long long oddCount = 0;  // 记录奇数选择的组合数  
​
    // 遍历数组中的每个数字
    for(auto i:numbers) {
        long long even = 0, odd = 0;  // 记录当前数字的偶数和奇数的个数
        while(i){
            int j = i % 10;
            i /= 10;
            if(j % 2 == 0) even++;
            else odd++;
        }
        // 处理完毕后,我们更新选择的组合数
        long long NewevenCount = evenCount * even + oddCount * odd;
        long long NewoddCount = oddCount * even + evenCount * odd;
        evenCount = NewevenCount;
        oddCount = NewoddCount;
    }
    return evenCount;
}
​
int main() {
    // You can add more test cases here
    std::cout << (solution({123, 456, 789}) == 14) << std::endl;
    std::cout << (solution({123456789}) == 4) << std::endl;
    std::cout << (solution({14329, 7568}) == 10) << std::endl;
    return 0;
}

反思

总结要点:

  1. 功能:

    • 函数 solution 接受一个整数向量 numbers,返回所有可能的组合,使得组合后的数字之和为偶数。
  2. 核心逻辑:

    • 初始化两个计数器:

      • evenCount: 记录当前组合中和为偶数的组合数,初始值为1(表示可以选择零个偶数)。
      • oddCount: 记录当前组合中和为奇数的组合数,初始值为0。
    • 遍历每个数字组,统计其中的偶数和奇数的数量。

    • 根据当前的偶数和奇数数量,更新组合计数器:

      • 新的偶数组合数 = 之前的偶数组合数 * 当前偶数数量 + 之前的奇数组合数 * 当前奇数数量。
      • 新的奇数组合数 = 之前的奇数组合数 * 当前偶数数量 + 之前的偶数组合数 * 当前奇数数量。
  3. 返回结果:

    • 最后返回 evenCount,即所有组合中和为偶数的组合数。
  4. 测试用例:

    • main 函数中,提供了几个测试用例来验证代码的正确性。

编译和运行

  • 使用 C++ 编译器编译代码并运行测试用例,输出结果表明每个测试用例是否通过。

复杂度

  • 时间复杂度是 O(n * m),其中 n 是数字组的数量,m 是每组的平均数字位数,适合处理较小规模的数据。

总体评价

还不错,这个代码竟然还可以输出奇数的选择组合数目,实在是太棒了