zoukankan      html  css  js  c++  java
  • 47. Permutations II

    Given a collection of numbers that might contain duplicates, return all possible unique permutations.

    Example:

    Input: [1,1,2]
    Output:
    [
      [1,1,2],
      [1,2,1],
      [2,1,1]
    ]
    class Solution {
          public List<List<Integer>> permuteUnique(int[] nums) {
            List<List<Integer>> res = new ArrayList<List<Integer>>();
            if(nums==null || nums.length==0) return res;
            boolean[] used = new boolean[nums.length];
            List<Integer> list = new ArrayList<Integer>();
            //排序有利于判断重复值
            Arrays.sort(nums);
            //深度优先算法
            dfs(nums, used, list, res);
            return res;
        }
    
        public void dfs(int[] nums, boolean[] used, List<Integer> list, List<List<Integer>> res){
            //如果结果长度和输入长度相等,则添加进结果集
            if(list.size()==nums.length){
                res.add(new ArrayList<Integer>(list));
                return;
            }
            for(int i=0;i<nums.length;i++){
                // 如果该元素已经被使用过,则继续遍历
                if(used[i]) continue;
                //下一个重复值只有在前一个重复值被使用的情况下才可以使用
                if(i>0 &&nums[i-1]==nums[i] && !used[i-1]) continue;
                used[i]=true;
                list.add(nums[i]);
                dfs(nums,used,list,res);
                used[i]=false;
                list.remove(list.size()-1);
            }
        }
    }

    和permutation1类似,多了一个判断重复元素的条件。

    下面是转载自https://segmentfault.com/a/1190000009513703的分析过程:

    “这里采用了递归的思路。避免重复的核心思路在于,使用一个boolean数组来代表当前的数值是否已经被使用过。当前的值如果已经被使用过,则继续判断下一个数值。如果当前的值为重复值,则只要前面的值没有被使用过,则当前值就不可以被使用。这样确保了只有第一个出现的重复值可以算进结果集,后序重复的情况不会被添加进结果集。
    例如,假设输入的数组为[1,1,2]。则当第一个1被添加进结果集时,可以继续使用第二个1作为元素添加进结果集从而生成112。同理,当试图将第二个1作为第一个元素添加进结果集时,只要第一个1还没有被使用过,则不可以使用第二个1。因此,112不会被重复的添加进结果集。
    其实,这个算法保证了所有重复的数字在结果集中的顺序和在原输入数组中的顺序是相同的。假设将[1,1,2]表示为[1,1#,2],那么结果集中会确保1永远在数值1#的前面,从而避免了11#2和1#12的重复情况出现。”

    public class Solution {
        public List<List<Integer>> permuteUnique(int[] nums) {
            List<List<Integer>> res = new ArrayList<List<Integer>>();
            if(nums == null || nums.length == 0){
                return res;
            }
            boolean [] used = new boolean[nums.length];
            helper(nums,used,new ArrayList<Integer>(), res);
            return res;
        }
        private void helper(int[] nums, boolean [] used, List<Integer> item, List<List<Integer>> res){
            if(item.size() == nums.length){
                if(!res.contains(item)){
                    res.add(new ArrayList<Integer>(item));
                }
                return;
            }
            for(int i = 0; i<nums.length; i++){
                if(!used[i]){
                    //if(i > 0 && nums[i-1] == nums[i] && !used[i-1]) continue;
                    used[i] = true;
                    item.add(nums[i]);
                    helper(nums,used,item,res);
                    item.remove(item.size()-1);
                    used[i] = false;
                }
            }
        }
    }

    半年了code没啥长进,偷懒的本事倒是加强了。

  • 相关阅读:
    03_ if 练习 _ little2big
    uva 11275 3D Triangles
    uva 12296 Pieces and Discs
    uvalive 3218 Find the Border
    uvalive 2797 Monster Trap
    uvalive 4992 Jungle Outpost
    uva 2218 Triathlon
    uvalive 3890 Most Distant Point from the Sea
    uvalive 4728 Squares
    uva 10256 The Great Divide
  • 原文地址:https://www.cnblogs.com/wentiliangkaihua/p/10412631.html
Copyright © 2011-2022 走看看