Subsets
One of the two basic templates of depth first search.
Definition
- Ordered sets of parent set
- Elements in subsets should be continuous
Example
If S = [1,2,3], its subsets is:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
Logical Steps
- Create a recursive helper function, start at a particular position in input as starting point.
- Recursively add element after position pointer into list (in a loop), and add lists into results.
- Backtrack to remove last element in previous list
- Move position cursor forward in next loop iteration for adding new elements into list.
Core Code Template
// Definition: nums, rst, list, pos
public void helper(nums, rst, list, pos) {
// base condition:
rst.add(new ArrayList<Integer>(list));
// loop through all elements after pos to construct a list
for (int i=pos; i<num.length; i++) {
// add curr element into list
list.add(num.get(i));
// recur call helper, with pos = i+1
helper(nums, rst, list, i+1);
// backtrack, remove last element from list
// and add in a different element next time
list.remove(list.size()-1);
}
}
Common Mistakes
- When adding list into results, directly add list object into result will create empty entries in result. Need to create a new Array List object for list.
- In helper function, will need a loop to go through all elements after start position, and call helper(nums, rst, list, i+1). If goes with no loop and helper(nums, rst, list, pos+1) directly, no new element can fill in to create new lists.
Follow Up: decuplication
There are duplicate numbers coming from input set, return all subsets. Each subset cannot have duplicate elements, but can contain different elements with the same value If S = [1,2,2], the subsets are:
[
[2],
[1],
[1,2,2],
[2,2], // the two 2's here are different elemt with same value
[1,2],
[]
]
Logical Steps: deduplication
- After backtrack, we need to make sure the element added into list (nums[i]) is not the previous element.
- Sort input numbers to put all duplicate numbers together
- Take only the first occurrence of duplicate numbers, since number position only appears in pos once, and only being taken when i=pos, all duplicate after i=pos are skipped.
Code Implementation: deduplicate
for (int i = pos; i<nums.length; i++) {
/**
* take first occurrence of duplicate numbers only
* (when first occurrence was at pos)
*/
if (i != pos && nums.get(i) == nums.get(i-1))
continue;
list.add(nums.get(i));
helper(nums, rst, list, i+1);
//backtrack
list.remove(list.size()-1);
}