问题描述
小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快速生成代码框架, 减少机械性编写工作,让我专注于思路调整与逻辑优化 。