您的位置:首页 > 其它

leetcode - 47. Permutations II(全排列)

2017-06-29 16:21 330 查看

47. Permutations II

Given a collection of numbers that mightcontain duplicates, return all possible unique permutations.

 

For example,

[1,1,2] have the following uniquepermutations:

[

 [1,1,2],

 [1,2,1],

 [2,1,1]

]

 

一题全排列的题目,并且在同一个集合里会出现重复的数字,这就需要除去相同序列,这里有两种方式:

一种是使用set来存储序列;

另外一种就是在遍历时就除去相同的序列;

两种方法本质上都是dfs。在solution板块看到了别人的解答,感觉受到启发。

这是一种在遍历时就除去相同的序列的方法。

 

算法思想

方法1:(使用set来除去相同的序列)

使用一个临时的线性表来保存当前的序列,并且再利用一个vis的线性表来保存访问记录,深度优先遍历(dfs)将未访问过的元素加入到临时的线性表中,加入元素至n个之后,将临时线性表加入set。

 

这里的主要时间花费在,dfs所花时间,O(n!),以及加入set中进行比较的时间O(nlogn),这显得有点不可以接受,不过总是比存在一个二维表里进行比较的O(n^2)要好上一点,最好的是利用hash_table,但操作难度就比较大。这里比较好的是只需要额外的操作空间是O(n)。

 

 

方法2:(在遍历过程中除去算法)

 

先将给定线性表排好序(方便遇上相同元素时直接跳过),然后进行遍历,当遇上相同元素时,直接跳入下一次遍历。

 

这里最重要的花费仍旧是dfs,还有就是拷贝vector所需要的代价,每一层迭代都要拷贝一个临时的vector。算法实现起来比较抽象,没有方法1那么简单。两种方法各有千秋,但在提交的时候偏向于第二种算法,运行时间相对较短。

class Solution {
public:
vector < vector<int> > ret;
vector <int> tmp;
set < vector<int> > my_set;
vector<vector<int>> permuteUnique(vector<int>& nums) {
//sort(nums.begin(), nums.end());
vector<int> vis(nums.size(),0);
//helper(nums,0,nums.size());
helper2(nums,vis,nums.size());
for(auto it = my_set.begin() ; it != my_set.end() ; ++it)ret.push_back(*it);
return ret;
}
void helper(vector<int> v , int i, int j){
if(i == j-1) {ret.push_back(v);return;}
for(int k = i ; k < j  ; ++k){
if(k != i && v[k] == v[i])continue;
swap(v[i],v[k]);
helper(v,i+1,j);
}

}

void helper2(vector<int>& v , vector<int>& vis , int n){
if(n == 0){my_set.insert(tmp);return;}
for(int i = 0 ; i < v.size() ; ++i){
if(!vis[i]){
vis[i] = 1;
tmp.push_back(v[i]);
helper2(v,vis,n-1);
vis[i] = 0;
tmp.pop_back();
}

}

}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode