递归实现三元方程解统计与打印问题求助
解决递归重复计数问题的修正方案
你的递归逻辑存在重复遍历同一三元组的问题,导致同一个解被多次计数,最终结果错误。比如解2 + 2 + 1会通过两条不同路径被访问:一条是先递增x1到2,再递增x2到2;另一条是先递增x2到2,再递增x1到2。每次到达这个组合时,你的代码都会计数一次,总数自然就会超出正确值。
核心解决思路
要避免重复计数,我们需要让每个(x1, x2, x3)组合只被遍历一次。可以通过固定递归的遍历顺序实现:按x1 → x2 → x3的顺序依次遍历每个变量的可能值,当某个变量达到上限(10)后,回溯到上一个变量递增,同时重置后续变量为初始值(1)。
修正后的递归代码(贴近原结构)
public static int solutions(int num) { if (num <3 || num > 30) return 0; return solutions(num, 1, 1, 1); } public static int solutions(int num, int x1, int x2, int x3) { int count = 0; // 检查当前组合是否为有效解 if (x1 + x2 + x3 == num) { System.out.println(x1+" + "+x2+" + "+x3); count = 1; } // 优先递增x3,直到达到上限10 if (x3 < 10) { count += solutions(num, x1, x2, x3 + 1); } // x3到上限后,递增x2,x3重置为1 else if (x2 < 10) { count += solutions(num, x1, x2 + 1, 1); } // x2和x3都到上限后,递增x1,x2和x3重置为1 else if (x1 < 10) { count += solutions(num, x1 + 1, 1, 1); } // 所有变量都到上限,返回累计计数 return count; }
代码工作原理
这个函数会严格按照以下顺序遍历所有可能的组合:(1,1,1) → (1,1,2) → ... → (1,1,10) → (1,2,1) → (1,2,2) → ... → (1,10,10) → (2,1,1) → ... → (10,10,10)
每个三元组只会被访问一次,因此不会出现重复计数。对于num=5,它会正确返回6并打印题目要求的所有解。
更简洁的分层递归方案
如果你希望逻辑更清晰,可以把递归拆分为两层,分别负责遍历x1和x2,直接计算x3是否合法:
public static int solutions(int num) { if (num < 3 || num > 30) return 0; return countX1(num, 1); } // 遍历x1的所有可能值 private static int countX1(int num, int x1) { if (x1 > 10) return 0; int count = 0; // 对每个x1,遍历x2的所有可能值 count += countX2(num, x1, 1); // 递归下一个x1 count += countX1(num, x1 + 1); return count; } // 遍历x2的所有可能值,计算对应的x3 private static int countX2(int num, int x1, int x2) { if (x2 > 10) return 0; int count = 0; int x3 = num - x1 - x2; // 检查x3是否在1-10范围内 if (x3 >= 1 && x3 <= 10) { System.out.println(x1 + " + " + x2 + " + " + x3); count++; } // 递归下一个x2 count += countX2(num, x1, x2 + 1); return count; }
这种方案的复杂度为O(100),比原代码的3^n效率高很多,同时逻辑更直观,容易理解和维护。
内容的提问来源于stack exchange,提问作者Dan




