Solution For Find Array Given Subset Sums
Problem Statement:
You are given an integer array nums of length n. The problem is to generate all possible arrays of length n that contains the given array nums exactly once and has the property that the sum of the elements in the array is equal to one of the given subset sums.
Return the lexicographically smallest array among all arrays that satisfy the above conditions. A result array is lexicographically smaller than another result array if it has a smaller first element, or if the first element is the same and the second element is smaller, and so on.
Input:
The input consists of two lines.
The first line contains a single integer n (1 ≤ n ≤ 18), the length of nums.
The second line contains n integers nums[i] (1 ≤ nums[i] ≤ 2000), the elements of nums.
Output:
Return the lexicographically smallest array among all arrays that satisfy the above conditions. If there is no such array, return an empty array.
Solution:
The problem requires us to find all the possible arrays containing exactly the same elements as the given array nums that have a sum equal to one of the subset sums of nums. We can solve this problem using backtracking.
We can start by generating all possible subset sums of nums using dynamic programming. We can create a boolean array dp of size (1 << n) and dp[i] will be true if there exists a subset of nums whose sum is equal to i. We can initialize dp[0] to true and for each element nums[j], we can set dp[i + nums[j]] to true for all i where dp[i] is true. Finally, we can iterate over dp and create a set of all subset sums.
We can then create an empty result array res of size n and initialize a boolean array used of size n to keep track of which elements of nums have been used in the current array. We can use backtracking to generate all possible arrays that satisfy the conditions. We can start by iterating over the possible subset sums in increasing order and for each sum s in the set, we can iterate over the elements of nums and check if the element has not already been used and if adding it to the current sum s will not exceed s. If both conditions are true, we can add the element to the result array, mark it as used and recursively call the function with the updated sum. If the length of the result array is equal to n and the current sum is equal to one of the subset sums, we have found a valid array and we can return it. Otherwise, we backtrack by removing the last added element from the result array and marking it as unused.
We can return the lexicographically smallest valid array we find. To compare two arrays, we can iterate over both of them and compare their corresponding elements. If we find an element in one of the arrays that is smaller than the corresponding element in the other array, we can stop iterating and return the smaller array.
Time Complexity:
The time complexity of this solution is O(2^n * n^2) where n is the length of nums. The dynamic programming step takes O(2^n * n) time and the backtracking step takes O(2^n * n^2) time in the worst case.
Space Complexity:
The space complexity of this solution is O(2^n * n) where n is the length of nums. We need an array dp of size (1 << n) for the dynamic programming step and a set of size (1 << n) to store the generated subset sums. We also need a boolean array used of size n and a result array of size n for the backtracking step.
Implementation:
Step by Step Implementation For Find Array Given Subset Sums
Given an array of integers arr and a list of integers a, your task is to find out whether or not a has a subset whose sum is exactly equal to integer b. If such a subset exists, return true. Otherwise, return false. Note: arr will always be a valid array with at least 1 element. 1 <= arr.length <= 10^5 1 <= arr[i] <= 1000 a will always be a valid list of integers with at least 1 element. 1 <= a.length <= 100 1 <= a[i] <= 1000 */ public class Solution { public boolean findArray(int[] arr, int[] a, int b) { // your code goes here // edge case if(a.length == 0 || arr.length == 0) { return false; } // create a hash set to store all the sums of the subsets of a HashSetset = new HashSet (); // create all the subsets of a and store the sum of each subset in the hash set for(int i = 0; i < (1 << a.length); i++) { int sum = 0; for(int j = 0; j < a.length; j++) { if((i & (1 << j)) > 0) { sum += a[j]; } } set.add(sum); } // check if any of the sums in the hash set is equal to b for(int i = 0; i < arr.length; i++) { if(set.contains(b - arr[i])) { return true; } } return false; } }
Given an array of integers arr and a list of integers a. Your task is to find out whether or not a given array arr can be partitioned into two subsets such that the sum of elements in both subsets is the same and all elements in the given array will be included in one partition or not. arr = [1, 2, 3, 4, 5, 6] a = [5, 7, 11] Output: true Explanation: The array can be partitioned as [1, 2, 3] and [4, 5, 6] such that the sum of elements in both subsets is the same and all elements in the array are included in one of the partitions.
var findArray = function(subsetSums, n) { // your code goes here };
There are many possible solutions to this problem. One approach is to use a hashtable to keep track of the sums of the subsets. Then, we can iterate through the array and check if the current sum is in the hashtable. If it is, we have found a subset that sums to the target sum. unordered_setsums; for (int i = 0; i < nums.size(); i++) { int currSum = 0; for (int j = i; j < nums.size(); j++) { currSum += nums[j]; if (sums.find(currSum) != sums.end()) { return true; } } sums.insert(currSum); } return false;
using System; public class Solution { // Function to find the array from // given subset sum array public static int[] FindArray( int[] subsetSum, int n) { // To store the starting // and ending index // of the first positive // subset sum int start = -1, end = -1; // Iterate through the // subset sum array for (int i = 0; i < n; i++) { // Check if the current // element is positive if (subsetSum[i] > 0) { start = i; break; } } // If no positive sum // is found if (start == -1) { return new int[] { -1 }; } // Iterate through the // subset sum array for (int i = n - 1; i >= start; i--) { // Check if the current // element is positive if (subsetSum[i] > 0) { end = i; break; } } // Variable to store // the length of the // required array int len = end - start + 1; // Declare the array int[] arr = new int[len]; // Variable to store the // sum of the required array int sum = 0; // Iterate through the // subset sum array for (int i = start; i <= end; i++) { // Add the current element // to the sum sum += subsetSum[i]; } // Variable to keep track // of the current index // of the required array int curr = 0; // Iterate through the // subset sum array for (int i = start; i <= end; i++) { // Check if the current // element is positive if (subsetSum[i] > 0) { // Divide the current element // by the sum to get // the current element // of the required array arr[curr] = subsetSum[i] / sum; // Update the sum sum -= arr[curr]; // Update the index curr++; } } // Return the required array return arr; } // Driver Code public static void Main() { int[] subsetSum = { 1, -3, 2, 5, 6, -1 }; int n = subsetSum.Length; int[] arr = FindArray(subsetSum, n); if (arr[0] == -1) { Console.WriteLine("No such array"); } else { Console.WriteLine("The required array is :"); for (int i = 0; i < arr.Length; i++) { Console.Write(arr[i] + " "); } } } } // This code is contributed by Smitha Dinesh Semwal