• Leetcode: Subsets II


    Given a collection of integers that might contain duplicates, S, return all possible subsets.
    
    Note:
    Elements in a subset must be in non-descending order.
    The solution set must not contain duplicate subsets.
    For example,
    If S = [1,2,2], a solution is:
    
    [
      [2],
      [1],
      [1,2,2],
      [2,2],
      [1,2],
      []
    ]

    第二遍Better做法:

    第11行 i>start && nums[i]==nums[i-1] 就skip很不错

     1 public List<List<Integer>> subsetsWithDup(int[] nums) {
     2     List<List<Integer>> list = new ArrayList<>();
     3     Arrays.sort(nums);
     4     backtrack(list, new ArrayList<>(), nums, 0);
     5     return list;
     6 }
     7 
     8 private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int start){
     9     list.add(new ArrayList<>(tempList));
    10     for(int i = start; i < nums.length; i++){
    11         if(i > start && nums[i] == nums[i-1]) continue; // skip duplicates
    12         tempList.add(nums[i]);
    13         backtrack(list, tempList, nums, i + 1);
    14         tempList.remove(tempList.size() - 1);
    15     }
    16 } 

    第一遍做法:需要已访问数组,当前后元素一样且前面元素并未访问,这个时候就是重复的case, continue, 

    注意这里的判重复条件跟3Sum那种是不一样的,

    3SUM防止重复方法是 if (i<num.length-1 && num[i]==num[i+1]) continue, 即当前starter如果与前一个相同,即跳过。这个做法在3sum可以,在这里不行。 3SUM这样做可以是因为它可以靠2SUM 子函数来确保找到non-duplicate的2set,然后只需要确保starter不一样,即可保证3set也non-duplicate. 然而这道题这里是recursion, 如果只判断当前starter与前一个一样就跳过,那么{2,2,3}都没法成为一个feasible set,因为第二个2需要被加入时总是被跳过。

    正确做法是需要设置已访问数组,当前后元素一样且前面元素并未访问,这个时候才是重复的case,才被跳过

     1     public ArrayList<ArrayList<Integer>> subsetsWithDup(int[] num) {
     2         ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
     3         ArrayList<Integer> item = new ArrayList<Integer>();
     4         if (num==null || num.length==0) return res;
     5         Arrays.sort(num);
     6         boolean[] visited = new boolean[num.length];
     7         for (int len=0; len<=num.length; len++) {
     8             helper(res, item, num, 0, len, visited);
     9         }
    10         return res;
    11     }
    12     
    13     public void helper(ArrayList<ArrayList<Integer>> res, ArrayList<Integer> item, int[] num, int starter, int len, boolean[] visited) {
    14         if (item.size() == len) {
    15             res.add(new ArrayList<Integer>(item));
    16             return;
    17         }
    18         for (int i=starter; i<num.length; i++) {
    19             if (i>0 && num[i]==num[i-1] && !visited[i-1]) continue;
    20             item.add(num[i]);
    21             visited[i] = true;
    22             helper(res, item, num, i+1, len, visited);
    23             item.remove(item.size()-1);
    24             visited[i] = false;
    25         }
    26     }
  • 相关阅读:
    linux系统常用命令
    oracle resetlog与noresetlog的作用(转载)
    RMAN备份之非归档模式下的备份
    查看oracle锁及解决办法
    夫夷以近,则游者众,险以远,则至者少!
    (转)一个10年程序员职业发展、总结和困境
    在myeclipse中写sql语句的细节问题
    myeclipse查询mysql出来的汉字是乱码
    如何将DB2的数据库转换到mySQL中?
    笔记本建立wifi热点的实用详细步骤
  • 原文地址:https://www.cnblogs.com/EdwardLiu/p/3958971.html
Copyright © 2020-2023  润新知