组合问题-含有重复元素(回溯算法)

 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 }

 

posted on 2025-03-01 23:21  faucon  阅读(4)  评论(0)    收藏  举报