Problem
Given an array write an algorithm to get or print all the possible sub subsequences.
Examples
Example 1:
Input: arr: [1, 2, 3]
Output: [[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
Solution
Method 1 - Bit manipulation and recursion
To generate all possible subsequences, we can use a recursive approach or an iterative approach using bit manipulation:
- Recursive Approach:
- For each element, we have two choices: either include the element in the current subsequence or exclude it.
- Recursively generate subsequences for both choices.
- Iterative Approach using Bit Manipulation:
- Each subsequence can be represented by a binary number where each bit represents whether the corresponding element is included in the subsequence.
- Iterate through all numbers from
0
to2^n - 1
(wheren
is the length of the array), and for each number, generate the subsequence corresponding to its binary representation.
Code
Java
public class Solution {
public List<List<Integer>> getAllSubsequences(int[] arr) {
List<List<Integer>> result = new ArrayList<>();
generateSubsequences(arr, 0, new ArrayList<>(), result);
return result;
}
private void generateSubsequences(int[] arr, int index,
List<Integer> current, List<List<Integer>> result) {
// Base case: add the current subsequence to the result
if (index == arr.length) {
result.add(new ArrayList<>(current));
return;
}
// Exclude the current element and move to the next
generateSubsequences(arr, index + 1, current, result);
// Include the current element and move to the next
current.add(arr[index]);
generateSubsequences(arr, index + 1, current, result);
current.remove(current.size() - 1); // backtrack
}
public static void main(String[] args) {
Solution solution = new Solution();
int[] arr = {1, 2};
List<List<Integer>> subsequences = solution.getAllSubsequences(arr);
System.out.println(
subsequences); // Expected output: [[], [1], [2], [1, 2]]
}
}
Python
class Solution:
def getAllSubsequences(self, arr: List[int]) -> List[List[int]]:
result = []
self.generateSubsequences(arr, 0, [], result)
return result
def generateSubsequences(
self,
arr: List[int],
index: int,
current: List[int],
result: List[List[int]],
):
# Base case: add the current subsequence to the result
if index == len(arr):
result.append(list(current))
return
# Exclude the current element and move to the next
self.generateSubsequences(arr, index + 1, current, result)
# Include the current element and move to the next
current.append(arr[index])
self.generateSubsequences(arr, index + 1, current, result)
current.pop() # backtrack
# Example usage
sol = Solution()
arr = [1, 2]
subsequences = sol.getAllSubsequences(arr)
print(subsequences) # Expected output: [[], [1], [2], [1, 2]]
Complexity
- ⏰ Time complexity:
O(n. 2^n)
, This is because there are (2^n) subsequences for an array of lengthn
, and generating each subsequence takesO(n)
time. - 🧺 Space complexity:
O(n. 2^n)
, for storing all subsequences.