(递归回溯)数字分组求偶数和(豆包Marscode 代码练习3)

题目链接:豆包 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. solution 方法

    • 该方法接收一个整数数组 numbers,并返回所有数字的奇偶数字组合中,和为偶数的组合数量。
    • 首先,将每个数字的数字分解成奇数列表和偶数列表。
    • 然后,使用回溯法查找所有组合并计算和为偶数的组合数量。
  2. backtrack 方法

    • 这是一个递归回溯函数,用于探索所有数字组合。
    • 递归基准情况是所有数字都处理完毕,如果当前和为偶数,返回 1;否则返回 0。
    • 在递归过程中,分别探索包含奇数位数字和偶数位数字的组合,并累加和为偶数的组合数量。
  3. main 方法

    • 该方法用于测试 solution 方法,确保其输出符合预期。
import java.util.ArrayList;
import java.util.List;

public class Main {

    /**
     * 计算输入整数数组中,所有数字的奇偶数字组合中,和为偶数的组合数量。
     *
     * @param numbers 整数数组。
     * @return 和为偶数的组合数量。
     */
    public static int solution(int[] numbers) {
        int count = 0; // 初始化和为偶数的组合数量计数器

        // 将每个数字的数字分解成奇数列表和偶数列表
        List<List<Integer>> oddLists = new ArrayList<>(); // 存储每个数字的奇数位数字的列表
        List<List<Integer>> evenLists = new ArrayList<>(); // 存储每个数字的偶数位数字的列表
        for (int num : numbers) {
            List<Integer> oddDigits = new ArrayList<>();
            List<Integer> evenDigits = new ArrayList<>();
            while (num > 0) {
                int digit = num % 10; // 获取最后一位数字
                if (digit % 2 == 0) {
                    evenDigits.add(digit); // 将偶数位数字添加到偶数列表
                } else {
                    oddDigits.add(digit); // 将奇数位数字添加到奇数列表
                }
                num /= 10; // 去掉最后一位数字
            }
            oddLists.add(oddDigits); // 将奇数位数字列表添加到奇数列表的列表中
            evenLists.add(evenDigits); // 将偶数位数字列表添加到偶数列表的列表中
        }

        // 使用回溯法查找所有组合并计算和为偶数的组合数量
        return backtrack(oddLists, evenLists, 0, 0);
    }

    /**
     * 递归回溯函数,用于探索所有数字组合。
     *
     * @param oddLists   奇数位数字列表的列表。
     * @param evenLists  偶数位数字列表的列表。
     * @param index      当前处理的数字索引。
     * @param currentSum 当前选择的数字之和。
     * @return 从当前点开始,和为偶数的组合数量。
     */
    private static int backtrack(List<List<Integer>> oddLists, List<List<Integer>> evenLists, int index, int currentSum) {
        // 递归基准情况:所有数字都处理完毕
        if (index == oddLists.size()) {
            return currentSum % 2 == 0 ? 1 : 0; // 如果当前和为偶数,返回 1;否则返回 0
        }

        int count = 0; // 初始化当前递归级别的计数器

        // 探索包含奇数位数字的组合
        for (int oddDigit : oddLists.get(index)) {
            count += backtrack(oddLists, evenLists, index + 1, currentSum + oddDigit);
        }

        // 探索包含偶数位数字的组合
        for (int evenDigit : evenLists.get(index)) {
            count += backtrack(oddLists, evenLists, index + 1, currentSum + evenDigit);
        }

        return count; // 返回从当前点开始的和为偶数的组合总数
    }

    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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值