二分数字组合&豆包AI辅助刷题体验 | 豆包MarsCode AI刷题

149 阅读4分钟

问题描述

小F面临一个有趣的挑战:给定一个数组,她需要将数组中的数字分为两组。分组的目标是使得一组数字的和的个位数等于给定的 A,另一组数字的和的个位数等于给定的 B。除此之外,还有一种特殊情况允许其中一组为空,但剩余数字和的个位数必须等于 A 或 B。小F需要计算所有可能的划分方式。

例如,对于数组 [1, 1, 1] 和目标 A = 1,B = 2,可行的划分包括三种:每个 1 单独作为一组,其余两个 1 形成另一组。如果 A = 3,B = 5,当所有数字加和的个位数为 3 或 5 时,可以有一组为非空,另一组为空。

测试样例

样例1:

输入:n = 3,A = 1,B = 2,array_a = [1, 1, 1]
输出:3

题目分析

条件一:一组数字的和的个位数等于给定的 A(or B)-> 实际我们只需要关注每个数组元素的个位数,在数值可能存在溢出时可以考虑做处理(num%10),同时也能推断出 0<=A(B)<=9

条件二:允许只满足A(or B),且B(or A)为空

条件三:元素间存在次序 -> 通过样例可以得出元素值相同下标不同视作不同的组合

做题思路

整个题目读下来第一时间让我想到 LeetCode全排列 ,先确定A的组合,使用(boolean)数组used记录元素使用,再从剩余元素中确定B的组合,这两个组合个数之和不需要刚好等于输入数组的长度,只要剩余元素之和为0即满足条件(其中若有多组合为0的情况需要另外计算)

尝试解题之前可以使用MarsCode AI给一点思路提示来拓宽我们的思路:

豆包给我们提供了一个有趣的思路,忽略组合内容直取sum,但在最后统计划分时只考虑了特殊情况(可以有一组为非空,另一组为空)。

尝试最初的思路解题,将思路喂给豆包

整个代码梳理下了核心部分基本符合我的预期想法,只需要微调几处bug就能完成解题了(豆包的理解力还是杠杠的,节省了很多代码编写时间)

把修改的想法喂一下看看

这里改动的不太如意,可能需要更细致的描述

直接自己动手!

public class Main {
    static int res=0;
    public static int solution(int n, int A, int B, int[] array_a) {
        //清除缓存
        res=0;

        //计算总和
        int totalSum = 0;
        for (int num : array_a) {
            totalSum += num;
        }

        // 如果总和的个位数既不等于 A 也不等于 B,直接返回 0
        if (totalSum%10 == A) {
           res++;
        }
        if(totalSum%10 == B){
            res++;
        }

        // 初始化布尔数组 used
        boolean[] used = new boolean[n];
        // 调用回溯函数
        backtrack(array_a, used, 0, 0, totalSum, A, B);
        
        // System.out.println(res);
        return res;
    }

    private static void backtrack(int[] array_a, boolean[] used, int index, int currentSum,int totalSum, int A, int B) {
        // 如果当前组合的和的个位数等于 A 或 B,返回 1
        if (currentSum % 10 == A && (totalSum-currentSum) % 10 == B) {
            res++;
        }

        // 遍历数组中的每个元素
        for (int i = index; i < array_a.length; i++) {
            if (!used[i]) {
                // 标记当前元素为已使用
                used[i] = true;

                // 递归调用回溯函数
                backtrack(array_a, used, i + 1, currentSum + array_a[i], totalSum, A, B);

                // 回溯,标记当前元素为未使用
                used[i] = false;
            }
        }
    }

    public static void main(String[] args) {
        //  You can add more test cases here
        int[] array1 = {1, 1, 1};
        int[] array2 = {1, 1, 1};
        int[] array3 = {1, 1};

        System.out.println(solution(3, 1, 2, array1) == 3);
        System.out.println(solution(3, 3, 5, array2) == 1);
        System.out.println(solution(2, 1, 1, array3) == 2);
    }
}

豆包AI刷题实践总结

1. 问题理解阶段

在解题时,豆包AI快速帮助分析了题目条件和边界,如条件一中通过 %10 提取个位数,从而规避了数值溢出的风险;条件三中明确“元素间次序重要”这一关键点,避免遗漏下标不同但值相同的情况。

这种快速提炼题目关键点的能力,帮助我迅速抓住解题方向,减少了对题目重复阅读和误解的时间。

2.提供新思路拓宽视野

豆包AI 的解题思路强调了直接利用总和计算的可能性,避免直接构造所有组合,降低了算法复杂度。这种“站在更高维度看问题”的启发,帮助我重新审视了解题思路:

  • 是否可以通过分解 totalSum 的个位数,快速判断是否满足条件?
  • 是否能避免复杂的全排列组合,直接从逻辑上剪枝?

虽然最终实现未完全采用该思路,但在优化过程中确实受到了启发。

3. 代码协助

将思路提供给豆包AI快速生成代码框架, 减少机械性编写工作,让我专注于思路调整与逻辑优化 。