Table of contents
Pattern 1 - Find all Subsequences
Given an integer array nums
of unique elements, return all possible (link) subsets
(the power set). The solution set must not contain duplicate subsets. Return the solution in any order.
Example 1:
Input: nums = [1,2,3]
Output: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
Example 2:
Input: nums = [0]
Output: [[],[0]]
Solution
Recursive Approach
Take & Not-Take
We start with an empty list and iterate through each index, adding the element at position (index - i) to explore all possible combinations. Similarly, we remove the element at index (i) and explore all resulting possibilities. Finally, upon reaching the end, we create a new list and add it to the answer list.
Time - O(2^n)
Space - O(n)
class Solution {
public void powerSet(int[] nums, int index, List<Integer> set, List<List<Integer>> ans){
if(index>=nums.length){
ans.add(new ArrayList<>(set));
return;
}
set.add(nums[index]);
powerSet(nums,index+1, set, ans);
set.remove(set.size()-1);
powerSet(nums,index+1, set, ans);
}
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
List<Integer> set = new ArrayList<>();
powerSet(nums,0, set, ans);
return ans;
}
}
Recursive Tree
Pattern 2 -Print all Subsequences whose sum is K
Example
Input: arr = [1,2,1], sum = 2
Output: [[1,1],[2]]
Code
public static void printSub(int[] arr, int index, int currentSum, int sum, List<Integer> currentSub, List<List<Integer>> ans){
if(index == arr.length){
if (currentSum==sum){
ans.add(new ArrayList<>(currentSub));
}
return;
}
currentSub.add(arr[index]);
currentSum+=arr[index];
printSub(arr,index+1,currentSum,sum,currentSub,ans);
currentSub.remove(currentSub.size()-1);
currentSum-=arr[index];
printSub(arr,index+1,currentSum,sum,currentSub,ans);
}
Caller code
public static void main(String[] args) {
int arr[] = {1,2,1};
int sum = 2;
List<List<Integer>> ans = new ArrayList<>();
printSub(arr,0,0,sum,new ArrayList<>(),ans);
System.out.println(ans);
}
/*
[[1, 1], [2]]
*/
Recursive Tree
Pattern 3 - Print any subsequence whose sum is target sum
Example
Input: arr = [1,2,1], sum = 2
Output: [1,1]
Code
public static boolean printSub(int[] arr, int index, int currentSum, int sum, List<Integer> currentSub){
if(index == arr.length){
if (currentSum==sum){
return true;
}
return false;
}
currentSub.add(arr[index]);
currentSum+=arr[index];
if (printSub(arr,index+1,currentSum,sum,currentSub)) return true;
currentSub.remove(currentSub.size()-1);
currentSum-=arr[index];
if(printSub(arr,index+1,currentSum,sum,currentSub)) return true;
return false;
}
Caller
public static void main(String[] args) {
int arr[] = {1,2,1};
int sum = 2;
List<Integer> currentSub = new ArrayList<>();
printSub(arr,0,0,sum,currentSub);
System.out.println(currentSub);
}
/*
[1, 1]
*/
Recursive Tree
Pattern 4 -Count the Subsequences with Sum k
Example
Input: arr = [1,2,1], sum = 2
Output: 2
Code
public static int countSub(int[] arr, int index, int currentSum, int sum){
if(index == arr.length){
if (currentSum==sum){
return 1;
}
return 0;
}
currentSum+=arr[index];
int leftCount = countSub(arr, index+1, currentSum,sum);
currentSum-=arr[index];
int rightCount = countSub(arr, index+1, currentSum, sum);
return leftCount+rightCount;
}
Caller
public static void main(String[] args) {
int arr[] = {1,2,1};
int sum = 2;
int count = countSub(arr,0,0,sum);
System.out.println(count);
}
Recursive Tree
Complexity
Time: (O(2^n)) - This accounts for all possible subsequence patterns.
Space: (O(n)) - Auxiliary stack space, corresponding to the height of the tree (n).