Given a collection of distinct numbers, return all possible permutations.
For example,
[1,2,3] have the following permutations:
[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1].
第一种方法。dfs
public class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> r = new ArrayList<List<Integer>>();
ArrayList<Integer> tmp = new ArrayList<Integer>();
if (nums.length == 0 || nums == null){
r.add(tmp);
return r;
}
dfs(r, tmp,nums, 0);
return r;
}
private void dfs(List<List<Integer>> r,ArrayList<Integer> tmp,int[] nums,int begin){
if (tmp.size() == nums.length) {
r.add(new ArrayList<Integer>(tmp));
return;
}
else {
for (int i = begin; i < nums.length; i++) {
tmp.add(nums[i]);
int t = nums[i];
nums[i] = nums[begin];
nums[begin] = t;
dfs(r, tmp, nums, begin+1);
tmp.remove(tmp.size()-1);
t = nums[i];
nums[i] = nums[begin];
nums[begin] = t;
}
}
}
}
也可以用BFS来做
public List<List<Integer>> permute(int[] nums) {
LinkedList<List<Integer>> r = new LinkedList<List<Integer>>();
ArrayList<Integer> tmp = new ArrayList<Integer>();
if (nums.length == 0 || nums == null){
r.add(tmp);
return r;
}
r.add(tmp);
for(int n:nums){
int size = r.size();
for(;size > 0;size--){
List<Integer> t = r.poll();
for(int i = 0;i <= t.size();i++){
List<Integer> cur = new ArrayList<Integer>(t);
cur.add(i,n);
r.add(cur);
}
}
}
return r;
}
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], and [2,1,1].
有可能出现重复。
最简单的方法是修改上面代码,增加查重;但查重效率很低,运行的很慢。
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> r = new ArrayList<List<Integer>>();
ArrayList<Integer> tmp = new ArrayList<Integer>();
if (nums.length == 0 || nums == null){
r.add(tmp);
return r;
}
dfs(r, tmp,nums, 0);
return r;
}
private void dfs(List<List<Integer>> r,ArrayList<Integer> tmp,int[] nums,int begin){
if (tmp.size() == nums.length) {
r.add(new ArrayList<Integer>(tmp));
System.out.println(tmp);
return;
}
else {
for (int i = begin; i < nums.length; i++) { //查重
for (int j = begin; j < i && i < nums.length; j++) {
if (nums[j] == nums[i]){
i++;
j = begin-1;
}
}
if(i == nums.length) return;
tmp.add(nums[i]);
int t = nums[i];
nums[i] = nums[begin];
nums[begin] = t;
dfs(r, tmp, nums, begin+1);
tmp.remove(tmp.size()-1);
t = nums[i];
nums[i] = nums[begin];
nums[begin] = t;
}
}
}
另一种方法是排序,可以降低查重难度。
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> r = new ArrayList<List<Integer>>();
ArrayList<Integer> tmp = new ArrayList<Integer>();
if (nums.length == 0 || nums == null){
r.add(tmp);
return r;
}
Arrays.sort(nums);
List<Integer> num = new ArrayList<Integer>();
boolean[] used = new boolean[nums.length];
dfs(r, tmp,nums, 0,used);
return r;
}
private void dfs(List<List<Integer>> r,ArrayList<Integer> tmp,int[] nums,int begin,boolean[] used){
if (tmp.size() == nums.length) {
r.add(new ArrayList<Integer>(tmp));
return;
}
else {
for (int i = 0; i < nums.length; i++) { //查重
if(used[i]) continue;
if(i > 0 && nums[i] == nums[i-1] && !used[i-1] ) continue;
tmp.add(nums[i]);
used[i] = true;
dfs(r, tmp, nums, begin+1,used);
tmp.remove(tmp.size()-1);
used[i] = false;
}
}
}
另,BFS方法只做了简单的修改,即用set来防止重复
public List<List<Integer>> permuteUnique(int[] nums) {
LinkedList<List<Integer>> r = new LinkedList<List<Integer>>();
ArrayList<Integer> tmp = new ArrayList<Integer>();
if (nums.length == 0 || nums == null){
r.add(tmp);
return r;
}
r.add(tmp);
for(int n:nums){
int size = r.size();
Set<String> set = new HashSet<String>();
for(;size > 0;size--){
List<Integer> t = r.poll();
for(int i = 0;i <= t.size();i++){
List<Integer> cur = new ArrayList<Integer>(t);
cur.add(i,n);
if(!set.contains(cur.toString())){
r.add(cur);
set.add(cur.toString());
}
}
}
}
return r;
}