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],
[3,2,1]
For example,
[1,2,3] have the following permutations:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
给定一个数组求全排列问题,经过观察可以发现,求全排列的过程中,我们都是先固定一个数,求剩下的全排列,直到剩下的数只有一个时,那全排列就是本身。用递归来解如下:
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> result = new ArrayList<List<Integer>>();//用来存放结果
List<Integer> num = new ArrayList<>();//用于将数组转化成list,方便去除固定的值,求剩下的全排列
for(int i=0;i<nums.length;i++)
num.add(nums[i]);
result = getLeft(num);
return result;
}
private List<List<Integer>> getLeft(List<Integer> nums) {
// TODO Auto-generated method stub
List<List<Integer>> result = new ArrayList<List<Integer>>();
if(nums.size()==1)
{
result.add(nums);
return result;//递归结束的地方
}
for(int i=0;i<nums.size();i++)
{
List<Integer> num = new ArrayList<>(nums);//用于去除掉当前值之后,传递给下一层进行全排列
num.remove(i);
List<Integer> temp = new ArrayList<>();
List<List<Integer>> r = getLeft(num);
Iterator<List<Integer>> it = r.iterator();
while(it.hasNext())
{
temp = (List<Integer>) it.next();
temp.add(0,nums.get(i));
result.add(temp);
}
}
return result;
}
}
47题是说给出的数组是有可能室友重复值的,那想到最简单的方法就是去重,Java中的set集合是可以自动去除重复值的,所以可以先用set来存储结果,然后再把set里的数据存到list中返回:
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
Set<List<Integer>> temp = new HashSet<List<Integer>>();
List<Integer> num = new ArrayList<>();
for(int i=0;i<nums.length;i++)
num.add(nums[i]);
temp = getLeft(num);
Iterator<List<Integer>> it = temp.iterator();
while(it.hasNext())
{
result.add(it.next());
}
return result;
}
private Set<List<Integer>> getLeft(List<Integer> nums) {
//TODO Auto-generated method stub
Set<List<Integer>> result = new HashSet<List<Integer>>();
if(nums.size()==1)
{
result.add(nums);
return result;
}
for(int i=0;i<nums.size();i++)
{
if(i>0 && nums.get(i-1)==nums.get(i))
continue;
else
{
List<Integer> num = new ArrayList<>(nums);
//temp.add(nums.get(i));
num.remove(i);
List<Integer> temp = new ArrayList<>();
Set<List<Integer>> r = getLeft(num);
Iterator<List<Integer>> it = r.iterator();
while(it.hasNext())
{
temp = (List<Integer>) it.next();
temp.add(0,nums.get(i));
result.add(temp);
}
}
}
return result;
}
}
如果不用set的话,可以先用sort函数对数组进行排序,保证重复的值在一起,那在求全排列时,总是先固定一个值求剩下值的全排列,那可以判断一下这个值与前面的值是否相等,如果相等的话就可以知道,固定当前值求剩下全排列的结果跟固定前一个值的结果是一样的,所以可以跳过,直到当前值与前一个值不一样为止:
public List<List<Integer>> permute(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> result = new ArrayList<List<Integer>>();
List<Integer> num = new ArrayList<>();
for(int i=0;i<nums.length;i++)
num.add(nums[i]);
result = getLeft(num);
return result;
}
private List<List<Integer>> getLeft(List<Integer> nums) {
// TODO Auto-generated method stub
List<List<Integer>> result = new ArrayList<List<Integer>>();
if(nums.size()==1)
{
result.add(nums);
return result;
}
for(int i=0;i<nums.size();i++)
{
if(i>0 && nums.get(i-1)==nums.get(i))//多加了一个重复值判断!!!!!!!
continue;
else
{
List<Integer> num = new ArrayList<>(nums);
//temp.add(nums.get(i));
num.remove(i);
List<Integer> temp = new ArrayList<>();
List<List<Integer>> r = getLeft(num);
Iterator<List<Integer>> it = r.iterator();
while(it.hasNext())
{
temp = (List<Integer>) it.next();
temp.add(0,nums.get(i));
result.add(temp);
}
}
}
return result;
}