Bitmasking
# since i am not confident about bitmasking
"""
# n
# mask = 1 << (k-1) for kth bit
# now bitwise AND = n & mask to see if kth bit is set to 1 or 0 (if n & mask == 1 -> kth bit is set to 1, else 0)
Subsets with recursion-:
Subsets without recursion-:
How to find subset of mask
Range of mask values = 0 to 2^n - 1 (7 is 2^3 - 1) for 3 bits.
2^n = 1 << n
2^0 = 1 << 0, 2^1 = 1 << 1, 2^2 = 1 << 2 so on..
for i in range(0, 2^n):
How to print the subsets??
1) Given mask -> parse from LSB to MSB (one bit at a time)
2) if jth posn bit is set in mask -> then include element else curr element
A B C
1 0 1
<--- j=0
0 0 1 mask
BITWISE = 0 0 1 = include 1 = C = {C}
j=1
0 1 0 mask
BITWISE = 0 0 0 = include nothing
j=1
BITWISE = 1 0 0 = include A = {AC}
{AC}
so basically
if (1 << j) & mask = 1, include jth element else skip jth element
"""
# Creating all subsets of given set of N elements
def subsets(N):
all_subsets = []
# runs 0 to 2^N times
for mask in range(1 << N):
cur_set = []
# runs N times
for j in range(N):
if mask & (1 << j):
cur_set.append(j)
all_subsets.append(cur_set)
return all_subsets
def subsets_recursion(N, idx=0, curr_set=None, all_subsets=None):
if curr_set is None:
curr_set = []
if all_subsets is None:
all_subsets = []
# base case
if idx == N:
all_subsets.append(curr_set[:])
return all_subsets
# include element
curr_set.append(idx)
subsets_recursion(N, idx + 1, curr_set, all_subsets)
# exclude elem
curr_set.pop()
subsets_recursion(N, idx + 1, curr_set, all_subsets)
return all_subsets
def main():
# (Ω(N × 2ᴺ))
print(subsets(3))
print(subsets_recursion(3)) # space: call stack -> O(n)
main()