• [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;
                    }
                }
            }
        }
    }
    

      

  • 相关阅读:
    BeanUtils.copyProperties的用法
    WinRAR下载
    安装Perl
    @Value设置默认值
    AutoHotkey
    解决springboot启动日志异常问题
    除以2换成位移操作(骚)
    IDEA生成doc文档生成chm文档
    VMWare虚拟机网络配置
    EOF小结
  • 原文地址:https://www.cnblogs.com/lautsie/p/3331150.html
Copyright © 2020-2023  润新知