Given a list of numbers with duplicate number in it. Find all unique permutations.
Have you met this question in a real interview?
Yes
Example
For numbers [1,2,2] the unique permutations are:
[
[1,2,2],
[2,1,2],
[2,2,1]
]
Challenge
Do it without recursion.
和上题一样,需要backtracking来做,上题的剪枝用的是记忆化搜索来查找是否已经被visited过了,这题如果画树状图的话,会发现和permutation一样, 需要放弃掉相同元素的出去第一个的其他元素(参考permutations II). 所以会看到在剪枝的时候用到 visited[i] 来确保当前元素是第一次出现在解里面,
这里有个很绕的地方, 做题的时候想了好久。。。
同时加了另外一个条件 i>0 && nums[i]==nums[i-1] && !visited[i-1] 来保证每一层不会出现重复的数字。 这个逻辑挺绕的,就是在第k个位置,如果我们有2, 2 连续两个数字,那么第一个2肯定没问题,第2个2我们是不能选的,那么如何排除呢,首先他和第一个2比是重复元素, 但是这里不能就直接丢掉,因为这里丢掉的话,当我们有一个(1,2)<2的解得情况下,也会把这个2丢掉, 这个时候比较tricky就是如果第一个2出现在第k层以前,那么他一定会把visited mark为true, 那么我们还是需要第二个2的, 我们知道第一个2按照顺序遍历,一定会先出现我们的解里面,但是回溯完以后,我们会把他visited设为false....这个好绕啊。。。但是!visited[i-1]就是从这里来的,意思为,这个数在同一层出现过一次了,不要了。
这里有个很绕的地方, 做题的时候想了好久。。。
同时加了另外一个条件 i>0 && nums[i]==nums[i-1] && !visited[i-1] 来保证每一层不会出现重复的数字。 这个逻辑挺绕的,就是在第k个位置,如果我们有2, 2 连续两个数字,那么第一个2肯定没问题,第2个2我们是不能选的,那么如何排除呢,首先他和第一个2比是重复元素, 但是这里不能就直接丢掉,因为这里丢掉的话,当我们有一个(1,2)<2的解得情况下,也会把这个2丢掉, 这个时候比较tricky就是如果第一个2出现在第k层以前,那么他一定会把visited mark为true, 那么我们还是需要第二个2的, 我们知道第一个2按照顺序遍历,一定会先出现我们的解里面,但是回溯完以后,我们会把他visited设为false....这个好绕啊。。。但是!visited[i-1]就是从这里来的,意思为,这个数在同一层出现过一次了,不要了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | class Solution { public: /** * @param nums: A list of integers. * @return: A list of unique permutations. */ vector<vector<int> > permuteUnique(vector<int> &nums) { // write your code here vector< vector<int> > result; if (nums.empty()) return result; sort(nums.begin(),nums.end()); vector<int> solution; vector<bool> visited(nums.size(), false); dfs(result, solution, nums, 0, visited); } void dfs(vector< vector<int> >& result, vector<int>& solution, vector<int>& nums, int level, vector<bool>& visited){ if (level == nums.size()){ result.push_back(solution); return; } for (int i=0; i<nums.size(); i++){ if (visited[i] || i>0 && nums[i]==nums[i-1] && !visited[i-1] ) continue; solution.push_back(nums[i]); visited[i]=true; dfs(result, solution, nums, level+1,visited); solution.pop_back(); visited[i]=false; } } }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | class Solution { public: /** * @param nums: A list of integers. * @return: A list of unique permutations. */ vector<vector<int> > permuteUnique(vector<int> &nums) { // write your code here vector< vector<int> > result; if (nums.empty()) return result; sort(nums.begin(),nums.end()); vector<int> solution; vector<bool> visited(nums.size(), false); dfs(result, solution, nums, 0, visited); } void dfs(vector< vector<int> >& result, vector<int>& solution, vector<int>& nums, int level, vector<bool>& visited){ if (level == nums.size()){ result.push_back(solution); return; } for (int i=0; i<nums.size(); i++){ if (visited[i] ) continue; solution.push_back(nums[i]); visited[i]=true; dfs(result, solution, nums, level+1,visited); solution.pop_back(); visited[i]=false; while(i<nums.size()-1&& nums[i+1]==nums[i]) i++; } } }; |
No comments:
Post a Comment