1.题目
给定一个数字列表,返回其所有可能的排列
2.算法
算法一:这是一个np问题,方法还是原来那个套路,还是用一个循环递归处理子问题。前面的数有可能放到后面,所以我们需要维护一个used数组来表示该元素是否已经在当前结果中,因为每次我们取一个元素放入结果,然后递归剩下的元素,所以不会出现重复。
public ArrayList<ArrayList<Integer>> permute(int[] num) {
ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
if(num==null || num.length==0)
return res;
helper(num, new boolean[num.length], new ArrayList<Integer>(), res);
return res;
}
private void helper(int[] num, boolean[] used, ArrayList<Integer> item, ArrayList<ArrayList<Integer>> res)
{
if(item.size() == num.length)
{
res.add(new ArrayList<Integer>(item));
return;
}
for(int i=0;i<num.length;i++)
{
if(!used[i])
{
used[i] = true;
item.add(num[i]);
helper(num, used, item, res);
item.remove(item.size()-1);
used[i] = false;
}
}
}
算法二:假如不用递归来作,我们用迭代来做
这道题的基本思路是,每遍历数组中的一个元素,我们把他加到已经生成的全排列的每个位置
public ArrayList<ArrayList<Integer>> permute(int[] num) {
ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
if(num == null || num.length==0)
return res;
ArrayList<Integer> first = new ArrayList<Integer>();
first.add(num[0]);
res.add(first);
for(int i=1;i<num.length;i++)
{
ArrayList<ArrayList<Integer>> newRes = new ArrayList<ArrayList<Integer>>();
for(int j=0;j<res.size();j++)
{
ArrayList<Integer> cur = res.get(j);
for(int k=0;k<cur.size()+1;k++)
{
ArrayList<Integer> item = new ArrayList<Integer>(cur);
item.add(k,num[i]);
newRes.add(item);
}
}
res = newRes;
}
return res;
}