给定一个可包含重复数字的序列 nums按任意顺序 返回所有不重复的全排列。

示例 1:

  1. Input: nums = [1,1,2]
  2. Output:
  3. [[1,1,2],
  4. [1,2,1],
  5. [2,1,1]]

示例 2:

  1. Input: nums = [1,2,3]
  2. Output: [[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
  • All the integers of nums are unique.

思路

本题可构建一棵求解树,如下图所示:
47-1.png

采用一次DFS即可得到答案。

DFS是基于递归,本题的终止条件是:当前层数等于输入列表的长度时,终止递归。

由于要去重,我们使用STL的set来存放当前路径path

代码

  1. class Solution {
  2. public:
  3. vector<vector<int>> permuteUnique(vector<int>& nums) {
  4. vector< vector<int> > result;
  5. if( nums.size() == 0 ) return result;
  6. if( nums.size() == 1 ) {
  7. result.push_back( nums );
  8. return result;
  9. }
  10. bool visited[ nums.size() ];
  11. for(int i = 0; i < nums.size(); i++)
  12. visited[i] = false;
  13. vector<int> path;
  14. set< vector<int> > result_set;
  15. dfs(nums, 0, result_set, path, visited);
  16. for(auto it = result_set.begin(); it != result_set.end(); it++)
  17. result.push_back( *it );
  18. return result;
  19. }
  20. void dfs
  21. (
  22. vector<int>& nums,
  23. int level,
  24. set< vector<int> >& result_set,
  25. vector<int>& path,
  26. bool visited[]
  27. ) {
  28. // 1. Exit condition
  29. if(level == nums.size()) {
  30. result_set.insert( path );
  31. return;
  32. }
  33. // 2. Walk every node that not visited
  34. for(int i = 0; i < nums.size(); i++) {
  35. int node = nums[i];
  36. if( !visited[i] ) {
  37. visited[i] = true;
  38. path.push_back(node);
  39. dfs(nums, level+1, result_set, path, visited);
  40. path.pop_back();
  41. visited[i] = false;
  42. }
  43. }
  44. }
  45. };