6层嵌套for循环取85元素的6个组合,有没有更高效的实现方法?
组合计算优化方案
原来的6层嵌套循环实际生成的是6个下标的全排列,存在大量重复计算,85个元素选6个的无重复组合仅为C(85,6)=437,353,560次,仅为原计算量的千分之一左右,优化后耗时会大幅下降。
方案1:迭代优化(性能最优,无需递归)
直接修改嵌套循环的起始值,要求后续索引永远大于前一个索引,天然避免重复组合,同时省去所有不等判断逻辑,还可以通过复用集合对象减少开销:
public void findOptimal6Combination() { int size = list.size(); // 若原逻辑从下标1开始遍历,把i的起始值改为1即可 for(int i = 0; i <= size - 6; i++) { current6.add(list.get(i)); for(int j = i + 1; j <= size - 5; j++) { current6.add(list.get(j)); for(int k = j + 1; k <= size - 4; k++) { current6.add(list.get(k)); for(int l = k + 1; l <= size - 3; l++) { current6.add(list.get(l)); for(int m = l + 1; m <= size - 2; m++) { current6.add(list.get(m)); for(int n = m + 1; n <= size - 1; n++) { current6.add(list.get(n)); performOperation(); current6.remove(current6.size() - 1); } current6.remove(current6.size() - 1); } current6.remove(current6.size() - 1); } current6.remove(current6.size() - 1); } current6.remove(current6.size() - 1); } current6.remove(current6.size() - 1); } }
方案2:递归回溯(通用灵活,适配任意数量元素组合)
如果后续需要调整选取的元素数量,不用修改循环层数,用回溯递归实现更灵活,内置剪枝逻辑避免无效循环:
// 入口方法,传入需要选取的元素数量6即可 public void findOptimalCombination(int k) { // 若原逻辑从下标1开始遍历,把第三个参数改为1即可 backtrack(list, k, 0, new ArrayList<>()); } private void backtrack(List<?> source, int k, int startIndex, List<Object> current) { if (current.size() == k) { // 可直接把current传入运算方法,避免用全局变量更安全 performOperation(current); return; } // 剪枝逻辑:剩余可选元素不足时直接终止循环,避免无效遍历 for (int i = startIndex; i <= source.size() - (k - current.size()); i++) { current.add(source.get(i)); backtrack(source, k, i + 1, current); current.remove(current.size() - 1); } }
额外性能优化建议
- 尽量简化
performOperation的内部逻辑,可提前计算的常量全部放到循环外 - 若运算逻辑支持并行,可将组合拆分到多线程执行,进一步缩短耗时
- 避免在循环内部创建不必要的对象,降低GC频率
内容的提问来源于stack exchange,提问作者Vergyverg
相关产品推荐
相关产品推荐

