首页 > 代码库 > [LeetCode]47 Permutations II

[LeetCode]47 Permutations II

https://oj.leetcode.com/problems/permutations-ii/

http://blog.csdn.net/linhuanmars/article/details/21570835


public class Solution {
    public List<List<Integer>> permuteUnique(int[] num) 
    {
        // Solution A:
        // return permuteUnique_Swap(num);
        
        // Solution B:
        return permuteUnique_NP(num);
    }

    ////////////////////////
    // Solution B: NP
    //
    private List<List<Integer>> permuteUnique_NP(int[] num)
    {
        Arrays.sort(num);
        boolean[] used = new boolean[num.length];
        List<List<Integer>> results = new ArrayList<>();
        permuteUnique_NPhelp(num, used, new ArrayList<Integer>(), results);
        return results;
    }
    
    private void permuteUnique_NPhelp(int[] num, boolean[] used, List<Integer> items, List<List<Integer>> results)
    {
        if (items.size() == num.length)
        {
            results.add(new ArrayList<Integer>(items));
            return;
        }
        
        for (int i = 0 ; i < num.length ; i ++)
        {
            // If num[i] equals to some value been used before
            // continue
            // If used[i - 1] == true, that is the first time num[i] occurs.
            if (i > 0 && !used[i - 1] && num[i] == num[i - 1])
                continue;
            
            if (used[i])
                continue;
            
            used[i] = true;
            items.add(num[i]);
            
            permuteUnique_NPhelp(num, used, items, results);
            
            used[i] = false;
            items.remove(items.size() - 1);
        }
    }
    
    
    ////////////////////////
    // Solution A: Recursive swap
    //
    private List<List<Integer>> permuteUnique_Swap(int[] num) 
    {
        List<List<Integer>> result = new ArrayList<>();
        perm(num, 0, result);
        return result;
    }

    private void perm(int[] n, int start, List<List<Integer>> result)
    {
        int len = n.length;
        if (start >= len)
        {
            // A result found.
            result.add(listof(n));
        }
        
        for (int i = start ; i < len ; i ++)
        {
            // If we have any dups from start to i.
            // No need to continue recursion
            // 
            // 注意不要误以为以下两种做法能够去重:
            // (1)最开始先对数组进行排序,以后每次交换时,只要保证当前要交换的元素和前一个元素不同,这种做法是错误的.
            // 虽然开始进行了排序,但是元素的交换会使数组再次变的无序
            // (2)每次进入递归函数permuteRecur时,对从当前索引开始的子数组排序,这种做法也是错误的.
            // 因为每次交换元素后,我们要恢复交换的元素,如果在递归函数内排序,就不能正确的恢复交换的元素。
            
            if (unique(n, start, i))
            {
                swap(n, i, start);
                perm(n, start + 1, result);
                swap(n, i, start);
            }
        }
    }
    
    private boolean unique(int[] n, int start, int end)
    {
        for (int i = start ; i < end ; i ++)
        {
            if (n[i] == n[end])
                return false;
        }
        return true;
    }
    
    private List<Integer> listof(int[] n)
    {
        List<Integer> toReturn = new ArrayList<>(n.length);
        for (int i : n)
            toReturn.add(i);
        return toReturn;
    }
    
    private void swap(int[] n, int i , int j)
    {
        int t = n[i];
        n[i] = n[j];
        n[j] = t;
    }
}


[LeetCode]47 Permutations II