// 定义一个Solution类,用于解决给定不重复整数数组的全排列问题
class Solution {
// 初始化结果集,用于存放所有不重复的全排列组合
List<List<Integer>> result = new ArrayList<>();
// 初始化路径变量,用于暂存当前递归生成的排列
List<Integer> path = new ArrayList<>();
// 公共方法:permuteUnique,输入一个不重复整数数组nums,返回该数组的所有全排列
public List<List<Integer>> permuteUnique(int[] nums) {
// 创建一个布尔数组,记录每个数字是否被使用过
boolean[] used = new boolean[nums.length];
// 对输入数组进行排序,以便在处理不重复元素时进行剪枝操作
Arrays.sort(nums);
// 调用回溯辅助函数开始搜索所有排列
backTrack(nums, used);
// 返回已找到的所有不重复排列结果集
return result;
}
// 回溯算法辅助函数:backTrack,输入原始数组nums和一个表示数字是否使用过的布尔数组used
private void backTrack(int[] nums, boolean[] used) {
// 当当前路径的元素个数等于原始数组的长度时,说明找到了一个新的合法排列
if (path.size() == nums.length) {
// 将当前排列添加到结果集中
result.add(new ArrayList<>(path));
return;
}
// 遍历数组中的每个元素
for (int i = 0; i < nums.length; i++) {
// 如果当前元素已经使用过(同层或同支),则根据情况跳过本次循环
if (i > 0 && nums[i] == nums[i - 1] && !used[i - 1]) {
continue; // 同一层中,若前一元素未使用且与当前元素相同,则跳过,避免产生重复排列
}
// 若当前元素没有使用过
if (!used[i]) {
// 标记当前元素为已使用
used[i] = true;
// 将当前元素添加到路径中
path.add(nums[i]);
// 以当前路径为基础,进行下一层递归查找其他可能的排列
backTrack(nums, used);
// 回溯过程:从路径中移除当前元素,并将其标记为未使用
path.remove(path.size() - 1);
used[i] = false;
}
}
}
}
这段代码实现了一个求解不重复整数数组全排列的算法。其中backTrack函数通过深度优先搜索遍历所有可能的排列组合,并利用一个布尔数组used来确保在每层递归过程中不会重复选择相同的元素(同一树枝)。当遇到相等但未使用的相邻元素时,会跳过以避免生成重复排列。最终将满足条件的排列存储在result变量中。