Algorithm: backtracking array subarray eleven Subsets set four kinds of solution

topic

Address: https://leetcode.com/problems/subsets/

Given a set of distinct integers, nums, return all possible subsets (the power set).

Note: The solution set must not contain duplicate subsets.

Example:

Input: nums = [1,2,3]
Output:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]

1. DFS backtracking depth-first solution

Analytical thinking:

  1. Traverse the elements in the array, or choose, or not choose.
  2. Note that you can exit conditions if (nums == null || index == nums.length). Indicates a potential array is empty, index may have crossed the line and then added to the list of results.
package backtracking;

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

// https://leetcode.com/problems/subsets/
public class Subsets {

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

  public List<List<Integer>> subsets(int[] 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 index) {
    // exit
    if (nums == null || index == nums.length) {
      resultList.add(new ArrayList<Integer>(list));
      return;
    }

    // add item
    list.add(nums[index]);
    dfs(nums, resultList, list, index + 1);

    // not add item
    list.remove(list.size() - 1);
    dfs(nums, resultList, list, index + 1);
  }
}

2. traversal execution

From an empty list List<List<Integer>> outputListto start, add an empty list new ArrayList<Integer>(), through all the data (for example: {1, 2, 3}),

  1. Create a new empty list List<List<Integer>> newList,
  2. Through the list List<List<Integer>> outputList, all the children have been added on the new figures,
比如遍历到1[ ] > [1]
比如遍历到2[ ] > [2]
[1] > [1, 2]
  1. Through the list new ArrayList<Integer>(), the new generation of sub-list appended to the existing list List<List<Integer>> outputList.
    Here Insert Picture Description
public List<List<Integer>> subsetsWithRecursion(int[] nums) {
  List<List<Integer>> outputList = new ArrayList<List<Integer>>();
  outputList.add(new ArrayList<Integer>());
  for (int num: nums) {
    List<List<Integer>> newList = new ArrayList<List<Integer>>();
    for (List<Integer> list: outputList) {
      newList.add(new ArrayList<Integer>(list) {{ add(num); }});
    }

    for (List<Integer> list: newList) {
      outputList.add(list);
    }
  }

  return outputList;
}

3. Solution back, returns the specified length

Here Insert Picture Description

public List<List<Integer>> subsetsWithBacktrack(int[] nums) {
  List<List<Integer>> resultList = new ArrayList<List<Integer>>();
  for (int len = 0; len <= nums.length; len++) {
    // backtrack
    backtrack(nums, resultList, new ArrayList<Integer>(), 0, len);
  }

  return resultList;
}

private void backtrack(int[] nums, List<List<Integer>> resultList, List<Integer> list, int first, int len) {
  // exit
  if (list.size() == len) {
    resultList.add(new ArrayList<Integer>(list));
    return;
  }

  if (first == nums.length) {
    return;
  }
  list.add(nums[first]);
  backtrack(nums, resultList, list, first + 1, len);
  list.remove(list.size() - 1);
  backtrack(nums, resultList, list, first + 1, len);
}

4. The bit assembly

Algorithm idea from Donald E. Knuth . Assembled into an array of length with the same binary, if an add in, or do not add.
Here Insert Picture Description

public List<List<Integer>> subsetsWithBinarySorted(int[] nums) {
    List<List<Integer>> resultList = new ArrayList<List<Integer>>();
    int n = nums.length;

    for (int i = (int)Math.pow(2, n); i < (int)Math.pow(2, n + 1); i++) {
      // generate bitmask, from 0..00 to 1..11
      String bitmask = Integer.toBinaryString(i).substring(1);

      // append subset corresponding to that bitmask
      List<Integer> list = new ArrayList<Integer>();
      for (int k = 0; k < n; k++) {
        if (bitmask.charAt(k) == '1') {
          list.add(nums[k]);
        }
      }

      resultList.add(list);
    }

    return resultList;
  }

Download

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

reference

https://leetcode.com/problems/subsets/solution/

https://www-cs-faculty.stanford.edu/~knuth/taocp.html

Published 127 original articles · won praise 12 · views 20000 +

Guess you like

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