Given a collection of numbers that might contain duplicates, return all possible unique permutations.
For example,[1,1,2]
have the following unique permutations:
[ [1,1,2], [1,2,1], [2,1,1] ]
分析
因为可能出现重复的元素
1. 对数组进行排序,ascending的顺序
2. 对begin位置的元素交换的时候,保证交换的一定是不同的元素即可
使用 引用nums并且回溯之前再次swap的方法不能AC,很奇怪?不能AC的代码如下:
测试[1,1,2,2]数据,代码是ok的,但是测试[0,0,1,1,2,2]代码,虽然值相同,但是下面的代码并不是都能按照从小到大的顺序生成全排列。
下面的代码答案最后几个是:[..[2,2,1,0,0,1],[2,2,0,1,1,0],[2,2,0,1,0,1],[2,2,0,0,1,1]]
但是标准答案是: [..[2,2,0,1,1,0],[2,2,1,0,0,1],[2,2,1,0,1,0],[2,2,1,1,0,0]]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class Solution { public : vector<vector< int >> permuteUnique(vector< int >& nums) { vector<vector< int >> results; sort(nums.begin(), nums.end()); helper(results, 0, nums); return results; } void helper(vector<vector< int >> & results, int begin, vector< int > & nums){ if (begin == nums.size() - 1 ){ results.push_back(nums); return ; } for ( int i = begin; i < nums.size(); ++i){ if (i!= begin && (nums[begin] == nums[i] || nums[i] == nums[i - 1])) continue ; swap(nums[begin], nums[i]); helper(results, begin + 1, nums); swap(nums[begin], nums[i]); } } }; |
而使用传值的方式去DFS,则可以AC,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class Solution { public : vector<vector< int >> permuteUnique(vector< int >& nums) { vector<vector< int >> results; sort(nums.begin(), nums.end()); helper(results, 0, nums); return results; } void helper(vector<vector< int >> & results, int begin, vector< int > nums){ if (begin == nums.size() - 1 ){ results.push_back(nums); return ; } for ( int i = begin; i < nums.size(); ++i){ if (i!= begin && nums[begin] == nums[i]) continue ; swap(nums[begin], nums[i]); helper(results, begin + 1, nums); } } }; |
后来一步步分析,关键还就在于 这里的代码,swap之后,DFS之后,并没有再次进行swap还原。
例如:
假设DFS过程已经进行到下面: