Algorithm: Subsets II back thirteen non-overlapping subset of the array (three kinds of solution)

1. Topic

地址: https://leetcode.com/problems/subsets-ii/
Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set).

Note: The solution set must not contain duplicate subsets.

Example:

Input: [1,2,2]
Output:
[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]

2. DFS backtracking solution

Analytical thinking:

  1. To sort an array
  2. When the length of the list is less than or equal array length, when added to the result list
  3. If the current element with the same elements, is ignored.
package backtracking;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

// https://leetcode.com/problems/subsets-ii/
public class SubsetsII {

  public static void main(String[] args) {
    int[] nums = {1,2,2};
    SubsetsII obj = new SubsetsII();
    List<List<Integer>> resultList = obj.subsetsWithDup(nums);
    System.out.println(Arrays.toString(resultList.toArray()));
  }

  public List<List<Integer>> subsetsWithDup(int[] nums) {
    Arrays.sort(nums);
    List<List<Integer>> resultList = new ArrayList<List<Integer>>();
    // dfs
    dfs(nums, resultList, new ArrayList<Integer>(), 0);

    return resultList;
  }

  private void dfs(int[] nums, List<List<Integer>> resultList, List<Integer> list, int start) {
    if (start <= nums.length) {
      resultList.add(list);
    }
    int i = start;
    while (i < nums.length) {
      list.add(nums[i]);
      dfs(nums, resultList, new ArrayList<Integer>(list), i + 1);

      list.remove(list.size() - 1);
      i++;
      while (i < nums.length && nums[i] == nums[i - 1]) {
        i++;
      }
    }

  }
}


3. Method circulation for backtracking

Problem-solving ideas with the same as above, to re-judge sentences if (i > start && nums[i] == nums[i - 1]) continue;the more common inside backtracking algorithm, so it is in this way can also be solved.

public List<List<Integer>> subsetsWithDup(int[] nums) {
    Arrays.sort(nums);
    List<List<Integer>> resultList = new ArrayList<List<Integer>>();
    // dfs
    dfsWithFor(nums, resultList, new ArrayList<Integer>(), 0);
    //subsetsWithDupHelper(nums, resultList, new ArrayList<Integer>(), 0);

    return resultList;
  }

  private void dfsWithFor(int[] nums, List<List<Integer>> resultList, List<Integer> list, int start) {
    // exit
    if (start <= nums.length) {
      resultList.add(new ArrayList<>(list));
    }

    for (int i = start; i < nums.length; i++) {
      // duplicate case
      if (i > start && nums[i] == nums[i - 1]) {
        continue;
      }

      // pick up
      list.add(nums[i]);
      dfsWithFor(nums, resultList, list, i + 1);

      // not pick up
      list.remove(list.size() - 1);
    }
  }

4. The order of execution

Problem-solving ideas:

  1. Array nums ascending order
  2. One by one through the array nums elements
  3. If the current element and the last element is not the same, from the zero position to the existing list of results resultList traverse, the current element nums[i]will be added to the child list.
  4. If the current element and the last element of the same size from the start on the back of the results list, this way you can filter out the same elements.
public List<List<Integer>> subsetsWithDupIterate(int[] nums) {
  Arrays.sort(nums);
  List<List<Integer>> resultList = new ArrayList<List<Integer>>();
  List<Integer> list = new ArrayList<Integer>();
  resultList.add(list);

  int duplicateStart = 0;
  for (int i = 0; i < nums.length; i++) {
    int begin = 0;
    int size = resultList.size();
    if (i > 0 && nums[i] == nums[i - 1]) {
      begin = duplicateStart;
    }

    for (int k = begin; k < size; k++) {
      List<Integer> newList = new ArrayList<Integer>(resultList.get(k));
      newList.add(nums[i]);
      resultList.add(newList);
    }

    duplicateStart = size;
  }

  return resultList;
}

download

https://github.com/zgpeace/awesome-java-leetcode/blob/master/code/LeetCode/src/backtracking/SubsetsII.java

发布了127 篇原创文章 · 获赞 12 · 访问量 2万+

Guess you like

Origin blog.csdn.net/zgpeace/article/details/103922570