https://leetcode.cn/problems/permutations-ii/description/
给定一个可包含重复数字的序列 nums
,按任意顺序 返回所有不重复的全排列。
示例 1:
输入:nums = [1,1,2] 输出: [[1,1,2], [1,2,1], [2,1,1]]
示例 2:
输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
提示:
1 <= nums.length <= 8
-10 <= nums[i] <= 10
解法一(java):
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
boolean[] uses = new boolean[nums.length];
backStarck(result,new ArrayList<>(),nums,uses);
return result;
}
public void backStarck(List<List<Integer>> result,List<Integer> tmpList,int[] nums,boolean[] uses) {
if (tmpList.size() == nums.length) {
result.add(new ArrayList<>(tmpList));
return;
}
for (int i = 0 ; i < nums.length ; i++) {
if (uses[i] || (i > 0 && nums[i] == nums[i-1] && !uses[i-1])) {
continue;
}
uses[i] = true;
tmpList.add(nums[i]);
backStarck(result,tmpList,nums,uses);
tmpList.remove(tmpList.size() - 1);
uses[i] = false;
}
}
}
思路:回溯法,参考http://www.haijin.xyz/article/566
-
排序:首先对数组进行排序,使相同数字相邻,便于后续剪枝处理。
-
回溯函数:
backtrack
是核心递归函数,用于生成排列。-
终止条件:当前排列长度等于原数组长度时,将当前排列加入结果集。
-
循环遍历:遍历数组中的每个数字。
-
剪枝条件:如果当前数字已被使用,或者与前一个数字相同且前一个数字未被使用(避免重复),则跳过。
-
递归调用:标记当前数字为已使用,加入当前排列,递归调用,然后回溯(恢复状态)。
-
-
结果返回:最终返回所有不重复的排列。