组合问题-含有重复元素(回溯算法)
1 package org.example; 2 3 import java.util.ArrayList; 4 import java.util.Arrays; 5 import java.util.List; 6 7 public class Main { 8 9 // 主方法,用于测试 10 public static void main(String[] args) { 11 int[] nums = {2, 2, 3, 3}; 12 int k = 3; 13 List<List<Integer>> result = combine(nums, k); 14 for (List<Integer> combination : result) { 15 System.out.println(combination); 16 } 17 } 18 19 // 主函数,用于计算所有可能的组合 20 public static List<List<Integer>> combine(int[] nums, int k) { 21 List<List<Integer>> result = new ArrayList<>(); 22 Arrays.sort(nums); // 先对数组进行排序,方便处理重复元素 23 backtrack(result, new ArrayList<>(), nums, k, 0); 24 return result; 25 } 26 27 // 回溯函数,用于递归生成所有可能的组合 28 private static void backtrack(List<List<Integer>> result, List<Integer> tempList, int[] nums, int remain, int start) { 29 // 如果剩余需要选择的元素数量为0,说明当前组合已经满足条件,将其加入结果集 30 if (remain == 0) { 31 result.add(new ArrayList<>(tempList)); 32 return; 33 } 34 35 // 遍历数组中的元素,尝试将其加入当前组合 36 for (int i = start; i < nums.length; i++) { 37 // 如果当前元素与前一个元素相同,并且不是第一个元素,则跳过,避免重复组合 38 if (i > start && nums[i] == nums[i - 1]) { 39 continue; 40 } 41 42 // 将当前元素加入临时组合 43 tempList.add(nums[i]); 44 // 递归调用,继续选择下一个元素,注意remain减1,start为i+1 45 backtrack(result, tempList, nums, remain - 1, i + 1); 46 // 回溯,移除最后一个元素,尝试其他可能的组合 47 tempList.remove(tempList.size() - 1); 48 } 49 } 50 }