Display All Subsets of An Integer Array in JavaAn integer array (or array list) is given to us. Our task is to print all the subsets of the given integer array (excluding empty subsets). Note that the order in which subsets are displayed does not matter. Example 1: Input int inputArr[] = {1, 2, 3} Output: {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3} Example 2: Input int inputArr[] = {1, 2, 3, 4, 5} Output: {1}, {2}, {3}, {4}, {5}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {2, 3}, {2, 4}, {2, 5}, {3, 4}, {3, 5}, {4, 5}, {1, 2, 3}, {1, 2, 4}, {1, 2, 5}, {1, 3, 4}, {1, 3, 5}, (1, 4, 5}, {2, 3, 4}, {2, 3, 5}, {2, 4, 5}, {3, 4, 5}, {1, 2, 3, 4}, {1, 2, 3, 5}, {1, 2, 4, 5}, {1, 3, 4, 5}, {2, 3, 4, 5}, {1, 2, 3, 4, 5} Approach: Using BacktrackingWith the help of backtracking, we can generate all of the subsets of the given array. For every element, we have only two options. One is to include that element in the current subset. The other is to exclude that element from the current subset. In this way, we can generate all of the subsets of the given integer array. The steps are as follows: Step 1: Create a 2D array list answer for keeping all of the subsets. Step 2: Also create a list tmp for keeping the current subset. Step 3: Make a recursive method getSubset() that has the following four parameters: Step 4: One is for keeping the current index. The second one is for storing the current subset. The third one is for storing all of the generated subsets (2D list), and the fourth one is the input array. Step 5: Invoke the method with the current index as 0, empty current vector (initially, there will be no subset), the empty 2D list, and the input integer array. Step 6: In the getSubset() method, we include the ith element in to the list tmp and recursively invoke getSubset() with value i + 1. Step 7: When the method call is returned, we delete the ith element from the tmp list and then invoke getSubset() method again with i + 1. Step 8: If the value of i is the same as the size of the input array, then add the list tmp to the list answer. Step 9: Eventually, sort and display each of the subarrays that are there in the list answer. Now let's see the implementation of the steps mentioned above. FileName: SubsetIntArr.java Output: For the array list: [1, 2, 3] The subsets are: [ 1 2 3 ] [ 1 2 ] [ 1 3 ] [ 1 ] [ 2 3 ] [ 2 ] [ 3 ] For the array list: [1, 2, 3, 4, 5] The subsets are: [ 1 2 3 4 5 ] [ 1 2 3 4 ] [ 1 2 3 5 ] [ 1 2 3 ] [ 1 2 4 5 ] [ 1 2 4 ] [ 1 2 5 ] [ 1 2 ] [ 1 3 4 5 ] [ 1 3 4 ] [ 1 3 5 ] [ 1 3 ] [ 1 4 5 ] [ 1 4 ] [ 1 5 ] [ 1 ] [ 2 3 4 5 ] [ 2 3 4 ] [ 2 3 5 ] [ 2 3 ] [ 2 4 5 ] [ 2 4 ] [ 2 5 ] [ 2 ] [ 3 4 5 ] [ 3 4 ] [ 3 5 ] [ 3 ] [ 4 5 ] [ 4 ] [ 5 ] Complexity Analysis: It is evident that one recursive call leads to two more recursive calls. Considering this fact gives the time complexity (2N). Also, O(N) time requires printing each subset. Therefore, the total time complexity of the program is O(N x 2N). The 2-D array list stores all the subsets, and the total number of subsets is O(2N), and a subset can have the maximum O(N) size. Therefore, the space complexity of the program is O(N x 2N), where the total number of elements present in the input list is N. Implementation: Using Bit MaskingOne of the prominent techniques for finding all the subsets is to use bit masking. In this approach, we have to treat each element of the input list as its corresponding bit. If that bit is set, then we will include that element in the current subset; otherwise, not. Consider an array consisting of three elements. Int arr[] = {4, 5, 9}. Since there are three elements, we will take three bits. For three bits there are 8 (23 = 8) different possibilities 000, 001, 010, 011, 100, 101, 110, 111. If we consider the possibilities from left to the right, then the first possibility (000) does not include any element. The second possibility, 001, only includes 3rd element (arr[2]). The third possibility, 010, includes the 2nd element (arr[1]). The fourth possibility, 011, includes the 2nd and 3rd elements (arr[1] and arr[2]). The fifth possibility, 100, includes the 1st element (arr[0]), and so on. Thus,
Since we are not considering any empty subset, the subsets we get are: [9], [5], [5, 9], [4], [4, 9], [4, 5], [4, 5, 9] of the input array [4, 5, 9]. It is our required answer. Now let's see the steps involved. Step 1: Declare a 2-D list answer for keeping all of the subsets. Step 2: Start a for-loop for val from 1 to 2^{N} -1 Step 3: Also, start an inner for-loop from 0 to N - 1 Step 4: If the i^{th} bit in val is set to 1, then add the i^{th} element of the input array in the current subset. Step 5: Add each generated subset into the 2-D list answer. Step 6: Eventually, sort and display each list inside the 2-D list answer with the help of a new line. Now let's see the implementation of the steps mentioned above. FileName: SubsetIntArr1.java Output: For the array list: [1, 2, 3] The subsets are: [ 1 ] [ 2 ] [ 1 2 ] [ 3 ] [ 1 3 ] [ 2 3 ] [ 1 2 3 ] For the array list: [1, 2, 3, 4, 5] The subsets are: [ 1 ] [ 2 ] [ 1 2 ] [ 3 ] [ 1 3 ] [ 2 3 ] [ 1 2 3 ] [ 4 ] [ 1 4 ] [ 2 4 ] [ 1 2 4 ] [ 3 4 ] [ 1 3 4 ] [ 2 3 4 ] [ 1 2 3 4 ] [ 5 ] [ 1 5 ] [ 2 5 ] [ 1 2 5 ] [ 3 5 ] [ 1 3 5 ] [ 2 3 5 ] [ 1 2 3 5 ] [ 4 5 ] [ 1 4 5 ] [ 2 4 5 ] [ 1 2 4 5 ] [ 3 4 5 ] [ 1 3 4 5 ] [ 2 3 4 5 ] [ 1 2 3 4 5 ] Complexity Analysis: The time, as well as space complexity of the program is the same as the previous program. |