AI 刷题 4.数字分组求偶数和 题解 | 豆包MarsCode AI刷题

127 阅读4分钟

小M的数字组合问题

问题描述

小M面临一个有趣的挑战:她需要从多个数字组中选择数字,组成一个新的数,而这个新数的各位数字之和必须为偶数。数字组是由从1到9的数字组成的字符串,例如,给定的数字组可能是 ['123', '456', '789']。小M的任务是计算出有多少种不同的分组和选择方法可以达到这个目标。

例如,对于输入 ['123', '456', '789'],小M可以通过选择不同的组合来形成新的数,如 147, 149, 158 等,最终得出符合要求的组合总数。

示例

为了更清楚地理解这个问题,下面是一些测试样例:

  • 示例1:
    • 输入:numbers = ['123', '456', '789']
    • 输出:14
  • 示例2:
    • 输入:numbers = ['123456789']
    • 输出:4
  • 示例3:
    • 输入:numbers = ['14329', '7568']
    • 输出:10

这些示例展示了小M如何从不同的数字组中选择数字,并计算出符合条件的组合数量。

解题思路

为了解决这个问题,我们可以采用递归的方法生成所有可能的组合,并检查每一种组合的数字和是否为偶数。具体的步骤如下:

  1. 数字组转换:首先,将输入的字符串数字组转换为数字列表,以便后续处理。
  2. 递归生成组合:使用递归函数来生成从每个数字组中选择一个数字的所有组合。
  3. 计算和的偶性:在生成每一种组合后,检查其数字和是否为偶数。
  4. 计数符合条件的组合:如果组合的数字和为偶数,则将计数器加一。

这种方法能够确保我们遍历所有可能的组合,同时有效地检查每个组合的和的偶性。

解题代码

以下是实现上述思路的 Python 代码:

def solution(numbers):
    count = 0  # 初始化计数器,用于记录符合条件的组合数量

    # 将每个数字组转换为数字列表
    digit_groups = []
    for num in numbers:
        digits = []
        for char in str(num):
            digits.append(int(char))
        digit_groups.append(digits)

    # 生成所有可能的组合
    def generate_combinations(groups, index, current_combination):
        if index == len(groups):
            # 检查当前组合的和是否为偶数
            if sum(current_combination) % 2 == 0:
                nonlocal count  # 声明 count 是外部函数的变量
                count += 1  # 修改外部函数的变量
            return
        for digit in groups[index]:
            generate_combinations(groups, index + 1, current_combination + [digit])

    generate_combinations(digit_groups, 0, [])
    return count  # 返回符合条件的组合数量

if __name__ == "__main__":
    # 测试用例
    print(solution(['123', '456', '789']) == 14)  # 应该输出14
    print(solution(['123456789']) == 4)  # 应该输出4
    print(solution(['14329', '7568']) == 10)  # 应该输出10

解题思路详细解析

在实现过程中,我们首先将输入的字符串转换为数字列表,以便后续递归处理。然后,我们定义了一个递归函数 generate_combinations,负责生成所有可能的组合。具体步骤如下:

  1. 递归基础情况:当索引等于数字组的长度时,说明已经生成了一种完整的组合。在此,我们计算当前组合的和,并检查其是否为偶数。
  2. 递归遍历:在递归过程中,我们遍历当前数字组中的每个数字,并将其添加到当前组合中,接着递归调用自身以处理下一个数字组。
  3. 计数更新:如果当前组合的和为偶数,则更新计数器。

通过这种递归方法,我们能够有效地遍历所有可能的组合,并确保每种组合都被检查。

复杂度分析

在分析时间和空间复杂度时,可以得出如下结论:

  1. 时间复杂度:设数字组的数量为 m,每个数字组的平均大小为 k。我们需要生成 k^m 种组合,且每种组合都需要计算和,因此时间复杂度为 O(m * k^m)。

  2. 空间复杂度:递归调用的深度为 m,每次调用都需要存储当前组合,因此空间复杂度为 O(m)。

这种复杂度分析表明,虽然方法直观且易于实现,但在数字组数量和大小较大时,可能会导致性能问题。因此,在实际应用中,可能需要考虑优化策略。

总结思考

通过这个问题,我对递归和组合生成有了更深的理解。递归是一种强大的工具,能够有效地处理组合和排列问题。在实际编程中,常常需要在性能和可读性之间进行权衡,而选择合适的算法和数据结构是提升代码效率的关键。

在未来的学习中,我将继续关注如何通过优化递归算法来提高性能,例如使用动态规划或剪枝技术,减少不必要的计算。同时,我也会探索其他算法设计模式,以应对更复杂的问题。