可以借鉴我的上一篇博客(http://blog.csdn.net/gpwner/article/details/75212890)来简单得得到答案:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* @author
* @version 2017/7/5.19:28
*/
public class Demo {
public static void main(String[] args) {
int[] nums = {1, 2, 1};
List<List<Integer>> result = new Demo().permuteUnique(nums);
for (List<Integer> integers : result) {
for (Integer integer : integers) {
System.out.print(integer + " ");
}
System.out.println();
}
}
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
helper(res, nums, 0);
return res;
}
private void helper(List<List<Integer>> res, int[] nums, int start) {
if (start == nums.length - 1) {
//将int[]转换为List
List<Integer> temp = IntStream.of(nums).boxed().collect(Collectors.toList());
res.add(temp);
return;
}
for (int i = start; i < nums.length; ++i) {
if (isDuplicate(nums, start, i))
continue;
swap(nums, start, i);
helper(res, nums, start + 1);
swap(nums, start, i);
}
}
private void swap(int[] A, int i, int j) {
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
private boolean isDuplicate(int[] nums, int i, int j) {
//注意这里一定是小于,不能是小于等于
while (i < j) {
if (nums[i] == nums[j])
return true;
i++;
}
return false;
}
}
这种办法效率比较低,因为每一次 都要比较,很耗时间
新办法:
在做全排列之前,首先统计出每一个元素的个数,将数组1,1,2的元素进行统计,得到item={1,2},count={2,1}表示在待全排序的数组中元素1的个数为2,元素2的个数为1。然后再进行全排列的时候遍历item数组,level表示排列好的数组元素的下标,level=0表示第一个元素,level=1表示第二个元素,level=2表示第三个元素,,,,,,,每一次取出一个元素的时候,count对应的位置就减一,做好这种排列之后再加回来。
用代码表示就是:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* @author
* @version 2017/7/5.19:28
*/
public class PermuteUnique {
public static void main(String[] args) {
int[] nums = {1, 2, 1};
List<List<Integer>> result = new PermuteUnique().permuteUnique(nums);
for (List<Integer> integers : result) {
for (Integer integer : integers) {
System.out.print(integer + " ");
}
System.out.println();
}
}
public List<List<Integer>> permuteUnique(int[] nums) {
Map<Integer, Integer> frequencies = new HashMap<>();
for (int i : nums) {
if (frequencies.containsKey(i)) {
int val = frequencies.get(i);
val++;
frequencies.put(i, val);
} else {
frequencies.put(i, 1);
}
}
//元素
int[] items = new int[frequencies.size()];
//元素对应的个数
int[] count = new int[frequencies.size()];
int index = 0;
for (Map.Entry<Integer, Integer> entry : frequencies.entrySet()) {
items[index] = entry.getKey();
count[index] = entry.getValue();
index++;
}
List<List<Integer>> result = new ArrayList<>();
//排列组合得到的数组,长度等于原来的数组
int[] permutation = new int[nums.length];
backtrack(items, count, permutation, result, 0);
return result;
}
//level 表示排列组合得到的数组的第几个位置,level=0表示第一个元素,level=1表示第二个元素,level=2表示第三个元素
private void backtrack(int[] items, int[] count, int[] permutation, List<List<Integer>> result, int level) {
if (level == permutation.length) {
List<Integer> validPermutation = IntStream.of(permutation).boxed().collect(Collectors.toList());
result.add(validPermutation);
}
for (int j = 0; j < items.length; j++) {
if (count[j] == 0)
continue;
permutation[level] = items[j];
count[j]--;
backtrack(items, count, permutation, result, level + 1);
count[j]++;
}
}
}