我发现 AI刷题 并没有官方题解,然后有时候 豆包大模型 给出来的代码并不能通过测试。基于此,我打算自己把所有题目都解答一次,然后附上我的 代码 和 解题思路。
问题描述
小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
在这里我说明一下我自己对递归代码的理解: 递归代码的核心在于 确定递归的终止条件 和 递归调用的逻辑。
- 定义问题(目标): 首先应该明确自己要解决的问题是什么,基于这个问题去设计递归函数。在解题初期,自己用手推的方式把想法清清楚楚地写出来,不要“含糊”。递归最忌讳“不明不白”。
- 确定递归函数的核心逻辑:
在递归代码中,最最重要的就是 函数的输入与输出 。即每次调用时,递归函数会接受特定的输入,并返回相应的输出,一定要明确下述亮点。
- 递归函数的参数表示什么?哪些参数会在递归中变化?
- 函数的返回表示什么?
- 设置递归终止条件:
终止条件或称为基线条件是递归的关键部分。它控制着递归何时结束,并防止无限循环。终止条件通常是问题的“最小规模”,即问题不可再分解时的情况。
- 数组处理到最后一个元素时停止
- 自己思考下,什么情况下 代码 走不动了
- 设计递归调用的逻辑:
如何通过分解问题逐步接近终止条件,你打算通过什么方式来 简化 问题
- 何在每次递归中修改参数,使得问题规模不断减小?
- 递归调用的返回值是如何通过组合或累加来形成最终结果的?也就是你最后想要的是什么
def solution(numbers):
"""
递归计算给定数组中的所有可能组合,使得组合的和为偶数的情况数。
实现思路:
1. 使用递归遍历`numbers`数组的每个数中的每个数字,逐一进行组合累加。
2. `current_sum` 用于保存当前组合的累加和。
3. 每当遍历完所有数组元素时,检查`current_sum`是否为偶数,若是,则计数+1。
4. 返回符合条件的组合数量。
"""
# 定义一个方法,用于检测目前 相加和 是否为偶数
def sum_(num):
return num % 2 == 0
def backtrack(current_sum, index):
"""
current_sum 表示当前的和。
index 表示当前处理的数字组索引。
count 表示目前找到的偶数和的组合数量。
"""
# 如果已经遍历完所有数字组
if index == len(numbers):
# 检查当前和是否为偶数
if sum_(current_sum):
return 1
else:
return 0
count = 0
# 将 numbers[index] 转换为字符串并进行迭代
for num in str(numbers[index]):
# 递归调用下一个数字组,累加当前数字到 current_sum
count += backtrack(current_sum + int(num), index + 1)
# 返回符合条件的组合数量
return count
# 初始调用递归函数,从第一个数字组开始,初始和为 0
return backtrack(0, 0)
if __name__ == "__main__":
# 测试样例
print(solution([123, 456, 789]) == 14)
print(solution([123456789]) == 4)
print(solution([14329, 7568]) == 10)