Skip to content

Commit f52c20c

Browse files
authored
Merge pull request #175 from BrianLusina/feat/algorithms-backtracking-find-subsets
feat(algorithms, backtracking): find subsets
2 parents d74b74f + c278439 commit f52c20c

17 files changed

Lines changed: 175 additions & 75 deletions

DIRECTORY.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@
3838
* [Test Generate Permutations](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/backtracking/permutations/generate_permutations/test_generate_permutations.py)
3939
* Restore Ip Addresses
4040
* [Test Restore Ip Addresses](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/backtracking/restore_ip_addresses/test_restore_ip_addresses.py)
41+
* Subsets
42+
* Cascading Subsets
43+
* [Test Cascading Subsets](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/backtracking/subsets/cascading_subsets/test_cascading_subsets.py)
44+
* Find All Subsets
45+
* [Test Find All Subsets](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/backtracking/subsets/find_all_subsets/test_find_all_subsets.py)
4146
* Word Search
4247
* [Constants](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/backtracking/word_search/constants.py)
4348
* [Point](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/backtracking/word_search/point.py)
@@ -307,11 +312,6 @@
307312
* Stack
308313
* Daily Temperatures
309314
* [Test Daily Temperatures](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/stack/daily_temperatures/test_daily_temperatures.py)
310-
* Subsets
311-
* Cascading Subsets
312-
* [Test Cascading Subsets](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/subsets/cascading_subsets/test_cascading_subsets.py)
313-
* Find All Subsets
314-
* [Test Find All Subsets](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/subsets/find_all_subsets/test_find_all_subsets.py)
315315
* Taxi Numbers
316316
* [Taxi Numbers](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/taxi_numbers/taxi_numbers.py)
317317
* Top K Elements
File renamed without changes.
File renamed without changes.

algorithms/subsets/cascading_subsets/__init__.py renamed to algorithms/backtracking/subsets/cascading_subsets/__init__.py

File renamed without changes.

algorithms/subsets/cascading_subsets/test_cascading_subsets.py renamed to algorithms/backtracking/subsets/cascading_subsets/test_cascading_subsets.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import unittest
22

3-
from algorithms.subsets.cascading_subsets import each_cons
3+
from algorithms.backtracking.subsets.cascading_subsets import each_cons
44

55

66
class CascadingSubsetsTestCase(unittest.TestCase):

algorithms/subsets/find_all_subsets/README.md renamed to algorithms/backtracking/subsets/find_all_subsets/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,20 @@ Given an array of integers, nums, find all possible subsets of nums, including t
2222
- Bit Manipulation
2323
- Backtracking
2424
- Arrays
25+
26+
---
27+
# Subsets II
28+
29+
Given an integer array nums, that can contain duplicate elements, return all possible subsets while ensuring that each
30+
subset is unique. The output must include unique subsets, and you may return them in any order.
31+
32+
## Constraints
33+
34+
- 1 <= `nums.length` <= 10
35+
- -10 <= `nums[i]` <= 10
36+
37+
## Examples
38+
39+
![Example 1](images/examples/find_all_subsets_ii_example_1.png)
40+
![Example 2](images/examples/find_all_subsets_ii_example_2.png)
41+
![Example 3](images/examples/find_all_subsets_ii_example_3.png)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
from typing import List
2+
3+
4+
def find_all_subsets(nums: List[int]) -> List[List[int]]:
5+
n = len(nums)
6+
7+
if n == 0:
8+
return []
9+
10+
subsets = []
11+
12+
def backtrack(first, curr):
13+
# Add the current subset to the output
14+
subsets.append(curr[:])
15+
# Generate subsets starting from the current index
16+
for i in range(first, n):
17+
curr.append(nums[i])
18+
backtrack(i + 1, curr)
19+
curr.pop()
20+
21+
backtrack(0, [])
22+
return subsets
23+
24+
25+
def find_all_subsets_with_duplicates(nums: List[int]) -> List[List[int]]:
26+
n = len(nums)
27+
28+
if n == 0:
29+
return []
30+
31+
# Sort in place to ensure that duplicate elements are next to each other, which will be used to skip over the duplicate
32+
# elements in the iteration.
33+
# Time complexity here is O(n log(n)) and space complexity is O(n) due to Timsort requiring space to handle sorting
34+
# in place
35+
nums.sort()
36+
37+
subsets: List[int] = []
38+
result: List[List[int]] = []
39+
40+
def backtrack(idx: int) -> None:
41+
"""
42+
Backtrack to create subsets from the given current index of the element being considered
43+
Args:
44+
idx(int): index of the element being considered.
45+
"""
46+
# Base case, if we reach the end of the list, we include the current subset to the result
47+
if idx == n:
48+
result.append(subsets[:])
49+
return
50+
51+
# Add the current subset to the output
52+
# Include the current element to the subset and move to the next element
53+
subsets.append(nums[idx])
54+
backtrack(idx + 1)
55+
# After recursion, remove it to backtrack and explore the excluded path
56+
subsets.pop()
57+
58+
# Skip the current element(exclude path), but skip duplicates too. If there are duplicate elements, skip them all
59+
# when choosing exclude path. This ensures that we only take one unique subset for each duplicate group
60+
while idx + 1 < n and nums[idx] == nums[idx + 1]:
61+
idx += 1
62+
backtrack(idx + 1)
63+
64+
backtrack(0)
65+
return result

algorithms/subsets/find_all_subsets/images/examples/find_all_subsets_example_1.png renamed to algorithms/backtracking/subsets/find_all_subsets/images/examples/find_all_subsets_example_1.png

File renamed without changes.

algorithms/subsets/find_all_subsets/images/examples/find_all_subsets_example_2.png renamed to algorithms/backtracking/subsets/find_all_subsets/images/examples/find_all_subsets_example_2.png

File renamed without changes.

algorithms/subsets/find_all_subsets/images/examples/find_all_subsets_example_3.png renamed to algorithms/backtracking/subsets/find_all_subsets/images/examples/find_all_subsets_example_3.png

File renamed without changes.

0 commit comments

Comments
 (0)