47. Permutations II
Leetcode Backtracking题目¶
Given a collection of numbers that might contain duplicates, return all possible unique permutations.
Example:
Input: [1,1,2]
Output:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
思路¶
这道题目和46. Permutations基本相同,唯一有区别的地方是排列的数字可能会重复。把结果放在set中,就可以除去重复的结果了。
public List<List<Integer>> permuteUnique(int[] nums) {
if (nums == null || nums.length == 0)
return new ArrayList<List<Integer>>();
Set<List<Integer>> list = new HashSet<>();
LinkedList<Integer> chosen = new LinkedList<>(),
numbers = new LinkedList<>();
for (int n : nums) numbers.add(n);
permuate(list, numbers, chosen);
return new ArrayList<List<Integer>>(list);
}
private void permuate(Set<List<Integer>> list,
LinkedList<Integer> nums, LinkedList<Integer> chosen) {
// base case
if (nums.size() == 0)
list.add(new ArrayList<Integer>(chosen));
for (int i = 0; i < nums.size(); i++) {
Integer n = nums.remove(i);
chosen.addLast(n); // chosen
permuate(list, nums, chosen); // explore
nums.add(i, n); // unchosen
chosen.removeLast();
}
}
class Solution {
public:
void permuteUniqueHelper(set<vector<int>> &result, vector<int>& nums, vector<int>& chosen){
if (nums.size()==0){
result.insert(chosen);
}else{
for (vector<int>::iterator iter=nums.begin(); iter!=nums.end(); iter++){
//choose
int s = *iter;
chosen.push_back(s);
nums.erase(iter);
//explore
permuteUniqueHelper(result, nums, chosen);
//unchoose
chosen.pop_back();
nums.insert(iter, s);
}
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<int> chosen;
set<vector<int>> result;
permuteUniqueHelper(result, nums, chosen);
vector<vector<int>> finals(result.begin(), result.end());
return finals;
}
};
另一种方法是先把数组排序,遍历时直接无视重复的数字。也就是说在当前的遍历中只遍历1个重复数字,剩下的重复数字在下一层次遍历中遍历,这样恰好使每一层遍历都遍历一个重复数字。能大幅减少运行时间。
public List<List<Integer>> permuteUnique(int[] nums) {
if (nums == null || nums.length == 0)
return new ArrayList<List<Integer>>();
List<List<Integer>> list = new ArrayList<>();
LinkedList<Integer> chosen = new LinkedList<>(),
numbers = new LinkedList<>();
Arrays.sort(nums);
for (int n : nums) numbers.add(n);
permuate(list, numbers, chosen);
return new ArrayList<List<Integer>>(list);
}
private void permuate(List<List<Integer>> list,
LinkedList<Integer> nums, LinkedList<Integer> chosen) {
// base case
if (nums.size() == 0) list.add(new ArrayList<Integer>(chosen));
for (int i = 0; i < nums.size(); i++) {
if (i > 0 && nums.get(i) == nums.get(i - 1)) continue;
Integer n = nums.remove(i);
chosen.addLast(n); // chosen
permuate(list, nums, chosen); // explore
nums.add(i, n); // unchosen
chosen.removeLast();
}
}
class Solution {
public:
void permuteUniqueHelper(vector<vector<int>> &res,
vector<int>& nums, vector<int>& chosen){
if (nums.size()==0){
res.push_back(chosen);
}else{
for (vector<int>::iterator iter=nums.begin();
iter!=nums.end(); iter++){
//遇到重复时,直接跳过
if ((iter!=nums.begin()) &&((*iter)==*(iter-1))){
} else{
//choose
int s = *iter;
chosen.push_back(s);
nums.erase(iter);
//explore
permuteUniqueHelper(res, nums, chosen);
//unchoose
chosen.pop_back();
nums.insert(iter, s);
}
}
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<int> chosen;
vector<vector<int>> res;
sort(nums.begin(), nums.end()); // 1. 排序
permuteUniqueHelper(res, nums, chosen);
return res;
}
};