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

152 阅读5分钟

数字分组求偶数和

问题描述

小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. 动态规划:我们可以用一个动态规划的方式来解决这个问题。维护两个状态:

每次从一个数字组中选择一个数字时,更新这两个状态。

    • even_count: 当前和为偶数的组合数。
    • odd_count: 当前和为奇数的组合数。
  1. 状态转移:假设当前考虑的是一个新的数字组:
    • 如果该数字组中有偶数,我们会将当前的组合从偶数转移到偶数,或从奇数转移到奇数。
    • 如果该数字组中有奇数,我们会将当前的组合从偶数转移到奇数,或从奇数转移到偶数。
  1. 最终结果:最后我们只需要返回最终状态中even_count的值,即符合条件的组合数。

代码实现

def count_even_sum_combinations(numbers):
    # 初始化dp数组,dp[0]表示和为偶数的组合数,dp[1]表示和为奇数的组合数
    even_count = 1  # 初始时和为偶数的组合为1种(没有选择数字时,和为0,偶数)
    odd_count = 0   # 和为奇数的组合数为0

    # 遍历每一组数字
    for group in numbers:
        # 临时存储新的even_count和odd_count
        new_even_count = 0
        new_odd_count = 0
        
        # 遍历每个数字,检查其奇偶性
        for num in group:
            if int(num) % 2 == 0:  # 偶数
                new_even_count += even_count  # 偶数不会改变和的奇偶性
                new_odd_count += odd_count    # 偶数也不会改变和的奇偶性
            else:  # 奇数
                new_even_count += odd_count  # 奇数会改变和的奇偶性
                new_odd_count += even_count  # 奇数也会改变和的奇偶性
        
        # 更新dp
        even_count = new_even_count
        odd_count = new_odd_count
    
    return even_count

# 测试样例
print(count_even_sum_combinations([123, 456, 789]))  # 输出: 14
print(count_even_sum_combinations([123456789]))     # 输出: 4
print(count_even_sum_combinations([14329, 7568]))   # 输出: 10

解释

  1. 初始化:开始时,even_count = 1,表示没有选择数字时,数字和为0,属于偶数。
  2. 遍历每个数字组:对于每个数字组,更新even_countodd_count。我们逐个判断数字是偶数还是奇数,并根据其影响更新组合的奇偶性。
  3. 计算结果:遍历完所有数字组后,even_count的值即为满足条件的组合数(即和为偶数的组合数)。

测试样例

  1. 样例1
print(count_even_sum_combinations([123, 456, 789]))

输出:14

  1. 样例2
print(count_even_sum_combinations([123456789]))

输出:4

  1. 样例3
print(count_even_sum_combinations([14329, 7568]))

输出:10

时间复杂度

  • 假设数字组的数量是n,每个数字组的长度最大为m,那么总的时间复杂度是O(n * m),因为我们需要遍历每个数字组中的每个数字来更新even_countodd_count
public class Main {

    public static int solution(int[] numbers) {
        // 初始化偶数和奇数的计数
        int evenCount = 1;  // 初始状态,和为偶数的组合数为1(不选择数字时,和为0)
        int oddCount = 0;   // 初始状态,和为奇数的组合数为0

        // 遍历每组数字
        for (int group : numbers) {
            // 判断当前数字的奇偶性
            int newEvenCount = 0;
            int newOddCount = 0;

            // 遍历当前数字的每一位
            while (group > 0) {
                int digit = group % 10;  // 获取当前数字的个位
                group /= 10;  // 去除个位

                // 如果是偶数,偶数不会改变和的奇偶性
                if (digit % 2 == 0) {
                    newEvenCount += evenCount;  // 偶数和为偶数
                    newOddCount += oddCount;    // 偶数和为奇数
                } else {
                    newEvenCount += oddCount;  // 奇数改变和的奇偶性
                    newOddCount += evenCount;  // 奇数改变和的奇偶性
                }
            }
            // 更新偶数和奇数的组合计数
            evenCount = newEvenCount;
            oddCount = newOddCount;
        }

        // 返回最终的偶数和组合数
        return evenCount;
    }

    public static void main(String[] args) {
        // 测试样例
        System.out.println(solution(new int[]{123, 456, 789}) == 14);
        System.out.println(solution(new int[]{123456789}) == 4);
        System.out.println(solution(new int[]{14329, 7568}) == 10);
    }
}