简体   繁体   中英

Subset Sum of K elemnts in O(2^(k/2)) Time

A little variation of the standard , Subset Sum Problem , is that we want to find a subset of K size from a set of N size ,which sums upto S .

The standard brute force solution for yields a complexity O(N^K) . But, the above link mentions a variation of brute force method , of complexity O(N^(K/2)) .

The wiki article says

A better exponential time algorithm is known which runs in time O(2N/2). The algorithm splits arbitrarily the N elements into two sets of N/2 each. For each of these two sets, it stores a list of the sums of all 2N/2 possible subsets of its elements. Each of these two lists is then sorted. Using a standard comparison sorting algorithm for this step would take time O(2N/2N). However, given a sorted list of sums for k elements, the list can be expanded to two sorted lists with the introduction of a (k + 1)st element, and these two sorted lists can be merged in time O(2k). Thus, each list can be generated in sorted form in time O(2N/2). Given the two sorted lists, the algorithm can check if an element of the first array and an element of the second array sum up to s in time O(2N/2). To do that, the algorithm passes through the first array in decreasing order (starting at the largest element) and the second array in increasing order (starting at the smallest element). Whenever the sum of the current element in the first array and the current element in the second array is more than s, the algorithm moves to the next element in the first array. If it is less than s, the algorithm moves to the next element in the second array. If two elements with sum s are found, it stops.

Now basically it says that if we want to find a subset of size k , we calculate n hash all subsets of size K/2 , along with their SUM, with sum being the key in hash.Then check whether two sets of size (k/2) sum upto S .

I understood the algo, but can't figure out, how can we go around to implement it. Hashing integers(Sum), with value being a list tuple,which contains the (K/2) indices of the actual set .

How can we implement it efficiently in C++.Using what Data sturctures ? Since a SUM of size (k/2) elements, can and will be non-unique, we cant use a MAP, we need a multi-map, or something like that.

Start with the basic O(2^n) brute force algorithm.

The improved algorithm, called the meet in the middle algorithm, splits the input list into equal-size halves. The first half is subject to the basic brute force algorithm, in which all subsets are generated, their sums computed, and the sums compared to the target. It is possible but unlikely that the target will be found in the first half. If not, the algorithm generates all subsets of the second half and checks each sum to see if the difference between target and sum was a sum in the first half, in which case the required subset has been found.

I give an implementation at my blog.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM