`

Leetcode - Permutation II

 
阅读更多
原题链接:https://leetcode.com/problems/permutations-ii/
[分析] 同Permutation一题的区别在于输入数组可能包含重复元素,在面试时即使面试官没有明确指出也该想到。如何处理重复元素不致得到重复结果呢?基本思路是排序然后跳过重复元素。Method1 每次循环递归都要排序且要复制一次数组,时间和空间消耗都比较大,Method2是Code Ganker大神的思路,使用一个额外数组used表示元素是否已经被排好位置。去重的关键是for循环一开始的if判断,理解起来有些费劲,大神的解释:只对第一个未被使用的进行递归,如果第一个重复元素前面的元素还没在当前结果中,那么我们不需要进行递归,这一次结果会出现在第一个的递归函数结果中。举例理解下:假设元素 a 有重复, 下标 i 和 i-1 处均是 a, 处理 i 下标时发现 i-1 下标的 a 还未被使用,这种情况下 i 应当跳过,因为循环是从前往后的推进的,i-1 已先被循环处理过,在这层递归中假设元素将排在位置 k 处,则若不跳过 i ,i 也被放在位置 k 处,最终将导致结果重复。

[ref] Code Ganker大神博客
http://blog.csdn.net/linhuanmars/article/details/21570835

public class Solution {
    public List<List<Integer>> permuteUnique2(int[] nums) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        if (nums == null || nums.length == 0)
            return result;
        Arrays.sort(nums);
        recur(nums, new boolean[nums.length], new ArrayList<Integer>(), result);
        return result;
    }
    public void recur(int[] nums, boolean[] used, List<Integer> item, List<List<Integer>> result) {
        if (item.size() == nums.length) {
            result.add(new ArrayList<Integer>(item));
            return;
        }
        for (int i = 0; i < nums.length; i++) {
            if (i > 0 && !used[i - 1] && nums[i] == nums[i - 1])
                continue;
            if (!used[i]) {
                item.add(nums[i]);
                used[i] = true;
                recur(nums, used, item, result);
                used[i] = false;
                item.remove(item.size() - 1);
            }
        }
    }
    
    public List<List<Integer>> permuteUnique(int[] num) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        if(num == null || num.length == 0)
            return result;
        Arrays.sort(num);
        return permutate(num, 0);
    }
    
    private List<List<Integer>> permutate(int[] num, int beg){
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        if(beg == num.length - 1){
            List<Integer> item = new ArrayList<Integer>();
            item.add(num[beg]);
            result.add(item);
            return result;
        }
        
        int origin = num[beg];
        for(int i = beg; i < num.length; i++){
            if(i != beg  && num[i] == num[i - 1])
                continue;
            num[beg] = num[i];
            num[i] = origin;
            
            int[] sub = Arrays.copyOf(num, num.length);
            Arrays.sort(sub, beg + 1, num.length);
            
            for(List<Integer> item : permutate(sub, beg + 1)){
                item.add(0, num[beg]);
                result.add(item);
            }
            num[i] = num[beg];
            num[beg] = origin;
        }
        return result;
    }
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics