[leetcode]Permutations II

要完成这道题,首先让我们再回顾一下SubSet II http://discuss.leetcode.com/questions/265/subsets-ii

1.每次进入sub的时候,都会记录当前path为一个结果(一个子集);
2.进入sub时,是用i个元素的子集来推导i+1个元素的子集的过程;
3.有了i个元素,第i+1个元素只从原始集合S的位置i之后的元素选;
4.该算法的关键是,有序添加。保证,产生的集合中的元素是有序的。
比如[1,2,3,4,5](暂不考虑重复)
如果进入sub的时候是[1,3],那么下一步是[1,3,4]和[1,3,5]
为什么没有[1,3,2]呢,因为[1,2]比如在[1,3]之前处理过了,它会处理到[1,2,3]的;
5.因为有序,那么已取的i个元素的集合中的最后一个元素,是一个分界。可以用它来判重。

http://www.cnblogs.com/lautsie/p/3249869.html

但对Permutation来说,本来就是尝试不同的顺序,没有有序这个概念,怎么弄呢?

答案是,递归时采用完全不同的方法。(上面这个方法,可能主要对求子集适用。)但在关键的判重部分,对重复的元素采用有序的思想。

例如:
输入为1 1 2,只要保证最后生成的组合中第二个1依旧在第一个1之后,就能保证不会出现重复的组合。
1 1 2,标记为1(1) 1(2) 2,它们能生成的所有组合
去掉1(2)在1(1)之前的情况:
1(1) 1(2) 2
1(1) 2 1(2)
2 1(1) 1(2)
即为所求。

方法采用的是:http://www.cnblogs.com/remlostime/archive/2012/11/13/2768816.html

先对数组进行排序,这样在DFS的时候,可以先判断前面的一个数是否和自己相等,相等的时候则前面的数必须使用了,自己才能使用,这样就不会产生重复的排列了。

最后,莫忘一开始排个序。还有将tmp添加到result里时要new一份,否则后面会被清空。

public class Solution {
    ArrayList<ArrayList<Integer>> ans = new ArrayList<ArrayList<Integer>>();
    ArrayList<Integer> tmp = new ArrayList<Integer>();
    public ArrayList<ArrayList<Integer>> permuteUnique(int[] num) {
        ans.clear();
        tmp.clear();
        Arrays.sort(num);
        int len = num.length;
        boolean[] canUse = new boolean[len];
        for (int i = 0; i < len; i++)
        {
            canUse[i] = true;
        }
        sub(num, canUse);
        return ans;
    }
    
    private void sub(int[] num, boolean[] canUse)
    {
        if (tmp.size() == num.length)
        {
            ans.add(new ArrayList<Integer>(tmp));
        }
        else
        {
            for (int i = 0; i < num.length; i++)
            {
                if (canUse[i])
                {
                    if (i!=0 && num[i] == num[i-1] && canUse[i-1]) continue;
                    tmp.add(num[i]);
                    canUse[i] = false;
                    sub(num, canUse);
                    tmp.remove(tmp.size()-1);
                    canUse[i] = true;
                }
            }
        }
    }
}

  

posted @ 2013-09-21 11:57  阿牧遥  阅读(705)  评论(0编辑  收藏  举报