Google Foobar最大可被3整除数字问题:Java代码测试失败求排查
问题分析与代码修正
你的代码核心错误在于元素筛选逻辑的优先级错误,以及未对mod1/mod2组排序导致无法保留最大元素,具体问题和修正方案如下:
错误点说明
盲目优先保留3个一组的mod元素,忽略全局最优
比如测试用例[2,2,1,1,1],总和为7,mod3余1。你的代码会先把3个mod1的1加入usable,得到结果111,但最优解是移除1个最小的1,保留2个2和2个1,组成2211——显然后者更大。你的逻辑没有基于全局总和的余数来选择最优保留策略,而是先处理3个一组的元素,导致错过更大的组合。mod1/mod2未排序,移除元素时选错对象
当需要移除元素时(比如余1时要移除1个mod1元素),应该移除组内最小的元素,才能保留更大的元素。你的代码直接按原数组顺序移除第一个元素,可能会误删大元素,导致结果变小。int存储结果存在潜在溢出风险
虽然题目中最多9个数字,最大数999999999在int范围内,但用String处理更稳妥,也符合大数处理的通用逻辑。
修正后的代码
import java.util.ArrayList; import java.util.Collections; public class Solution { public static int solution(int[] l) { ArrayList<Integer> mod0 = new ArrayList<>(); ArrayList<Integer> mod1 = new ArrayList<>(); ArrayList<Integer> mod2 = new ArrayList<>(); // 分组并按降序排序,方便后续移除最小元素 for (int num : l) { if (num % 3 == 0) { mod0.add(num); } else if (num % 3 == 1) { mod1.add(num); } else { mod2.add(num); } } Collections.sort(mod0, Collections.reverseOrder()); Collections.sort(mod1, Collections.reverseOrder()); Collections.sort(mod2, Collections.reverseOrder()); // 计算总和的mod3余数 int sum = 0; for (int num : l) sum += num; int remainder = sum % 3; // 根据余数调整需要保留的元素 if (remainder == 1) { // 优先移除1个mod1的最小元素 if (!mod1.isEmpty()) { mod1.remove(mod1.size() - 1); } else { // 若mod1为空,移除2个mod2的最小元素 if (mod2.size() >= 2) { mod2.remove(mod2.size() - 1); mod2.remove(mod2.size() - 1); } else { // 无法组成符合条件的数 return 0; } } } else if (remainder == 2) { // 优先移除1个mod2的最小元素 if (!mod2.isEmpty()) { mod2.remove(mod2.size() - 1); } else { // 若mod2为空,移除2个mod1的最小元素 if (mod1.size() >= 2) { mod1.remove(mod1.size() - 1); mod1.remove(mod1.size() - 1); } else { // 无法组成符合条件的数 return 0; } } } // 合并所有可用元素 ArrayList<Integer> usable = new ArrayList<>(); usable.addAll(mod0); usable.addAll(mod1); usable.addAll(mod2); if (usable.isEmpty()) return 0; // 降序排序,组成最大数 Collections.sort(usable, Collections.reverseOrder()); // 处理全0的情况 if (usable.get(0) == 0) return 0; // 转换为数字(用String避免溢出) StringBuilder sb = new StringBuilder(); for (int num : usable) { sb.append(num); } return Integer.parseInt(sb.toString()); } }
修正逻辑说明
- 分组后降序排序:mod1和mod2组按降序排列,移除元素时取最后一个(最小元素),保证保留的元素尽可能大。
- 基于总和余数调整:根据所有元素总和的mod3余数,选择最优的移除策略:
- 余1:优先移除1个mod1最小元素,不行则移除2个mod2最小元素
- 余2:优先移除1个mod2最小元素,不行则移除2个mod1最小元素
- 全0处理:如果合并后的元素第一个是0,说明所有元素都是0,直接返回0。
- String拼接结果:避免int溢出,同时方便处理大数。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

