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 }