Partition array into K subsets of same sum value - java

trying to figure out following problem:
Given a set S of N positive integers the task is to divide them into K subsets such that the sum of the elements values in every of the K subsets is equal.
I want to do this with a set of values not more than 10 integers, with values not bigger than 10 , and less than 5 subsets.
All integers need to be distributed, and only perfect solutions (meaning all subsets are equal, no approximations) are accepted.
I want to solve it recursively using backtracking. Most ressources I found online were using other approaches I did not understand, using bitmasks or something, or only being for two subsets rather than K subsets.
My first idea was to
Sort the set by ascending order, check all base cases (e.g. an even distribution is not possible), calculate the average value all subsets have to have so that all subsets are equal.
Going through each subset, filling each (starting with the biggest values first) until that average value (meaning theyre full) is achieved.
If the average value for a subset can't be met (undistributed values are too big etc.), go back and try another combination for the previous subset.
Keep going back if dead ends are encountered.
stop if all dead ends have been encountered or a perfect solution was found.
Unfortunately I am really struggling with this, especially with implementing the backtrack and retrying new combinations.
Any help is appreciated!

the given set: S with N elements has 2^N subsets. (well explained here: https://www.mathsisfun.com/activity/subsets.html ) A partition is is a grouping of the set's elements into non-empty subsets, in such a way that every element is included in one and only one of the subsets. The total number of partitions of an n-element set is the Bell number Bn.
A solution for this problem can be implemented as follows:
1) create all possible partitions of the set S, called P(S).
2) loop over P(S) and filter out if the sum of the elements values in every subsets do not match.

Related

Length of list pattern

I have a list where I am trying to find the sum of combination of the lists entries, except the entries where both values to add are equal to each other (ie 2+2 would not be added) and add them to another list.
As an example:
[1,2,3] would yield the list of sums [3,4,5] because 1+2=5,1+3=4, and 2+3=5
However, my issues arises with not knowing how many sums will be produced. I am working in java and am limited to native arrays, therefore the size of the array has to be set before I can add the sum values to it.
I know I would not be able to find the exact size of the sum list due to the possibility that a sum would not get added if the two elements are the same, but I am trying to ballpark it so I don't have massive arrays.
The closest 'formula' I have gotten is setting the following, but it is never precisely what the max value would be for any list
(list length of original numbers * list length of original numbers) / 2
I am trying to keep time complexity in mind, so keeping a running count of how many sums there are, setting an array to that size, and looping through the original list again would not be efficient.
Any suggestions?
Can you add same sums to array, I mean, your array is {1,2,3,4,5}. Would you print the both result of 1+5 and 2+4 =6.
If your answer is yes. You can get the length of array and multiply it with 1 less and divide them to 2. For instance; our array → {1,2,3,4,5} the lenght is 5 the length of our result array will be 5*4/2=10.
Or you can use lists in java if you cant define a length for array. Keep in mind.

Find the only unique element in an array of a million elements

I was asked this question in a recent interview.
You are given an array that has a million elements. All the elements are duplicates except one. My task is to find the unique element.
var arr = [3, 4, 3, 2, 2, 6, 7, 2, 3........]
My approach was to go through the entire array in a for loop, and then create a map with index as the number in the array and the value as the frequency of the number occurring in the array. Then loop through our map again and return the index that has value of 1.
I said my approach would take O(n) time complexity. The interviewer told me to optimize it in less than O(n) complexity. I said that we cannot, as we have to go through the entire array with a million elements.
Finally, he didn't seem satisfied and moved onto the next question.
I understand going through million elements in the array is expensive, but how could we find a unique element without doing a linear scan of the entire array?
PS: the array is not sorted.
I'm certain that you can't solve this problem without going through the whole array, at least if you don't have any additional information (like the elements being sorted and restricted to certain values), so the problem has a minimum time complexity of O(n). You can, however, reduce the memory complexity to O(1) with a XOR-based solution, if every element is in the array an even number of times, which seems to be the most common variant of the problem, if that's of any interest to you:
int unique(int[] array)
{
int unpaired = array[0];
for(int i = 1; i < array.length; i++)
unpaired = unpaired ^ array[i];
return unpaired;
}
Basically, every XORed element cancels out with the other one, so your result is the only element that didn't cancel out.
Assuming the array is un-ordered, you can't. Every value is mutually exclusive to the next so nothing can be deduced about a value from any of the other values?
If it's an ordered array of values, then that's another matter and depends entirely on the ordering used.
I agree the easiest way is to have another container and store the frequency of the values.
In fact, since the number of elements in the array was fix, you could do much better than what you have proposed.
By "creating a map with index as the number in the array and the value as the frequency of the number occurring in the array", you create a map with 2^32 positions (assuming the array had 32-bit integers), and then you have to pass though that map to find the first position whose value is one. It means that you are using a large auxiliary space and in the worst case you are doing about 10^6+2^32 operations (one million to create the map and 2^32 to find the element).
Instead of doing so, you could sort the array with some n*log(n) algorithm and then search for the element in the sorted array, because in your case, n = 10^6.
For instance, using the merge sort, you would use a much smaller auxiliary space (just an array of 10^6 integers) and would do about (10^6)*log(10^6)+10^6 operations to sort and then find the element, which is approximately 21*10^6 (many many times smaller than 10^6+2^32).
PS: sorting the array decreases the search from a quadratic to a linear cost, because with a sorted array we just have to access the adjacent positions to check if a current position is unique or not.
Your approach seems fine. It could be that he was looking for an edge-case where the array is of even size, meaning there is either no unmatched elements or there are two or more. He just went about asking it the wrong way.

Maximum product of 3 numbers in an array

I came across this question in a recent interview.
Given an array find the maximum product that can be obtained multiplying any 3 numbers in the array.
The solution I came up with is,
Sort the array
Multiply the 3 largest number.
This is O(nlogn)
Is there a O(n) solution to the problem?
Instead of sorting all the values, you can retain the top three, which is O(3n) which is O(n)
Doing this in a single pass is likely to be more efficient than three passes.
One way of doing this is to do an insertion sort into an array of 3, discarding the lowest value each time. (you can start at the lowest value in the array)
You can also implement this using a series of if/else comparison to update 3 variables.
How about negatives?
The only complication is if you can have negative values e.g. 5 * -4 * -4 > 5 * 5 * 3
For this reason it would makes sense to search for the three largest and the two most negative. You can check whether the largest * the next two largest or largest * the two most negative is bigger.
what if they are all negative?
In this case, you also need the three smallest negative values as well to get the product closest to positive infinity.
You can do it in O(n) as follows:
Find the largest number in O(n); remove the number from the array (make it zero)
Find the largest number among the remaining numbers in O(n); make it zero as well
Find the largest number among the remaining numbers, again in O(n)
You repeat the same O(n) loop three times, so it's O(3*n), which is the same as O(n) because constants are ignored.
This won't cater to negatives
It is relatively easy to modify this algorithm to work with negative numbers. Each pass through the array needs to find the largest and the smallest negative value, so at the end you would have three large positive numbers P0, P1, P2 and thee large negative numbers N0, N1, N2, in ascending order by magnitude. Now you need to compare P0*P1*P2 vs. N1*N2*P2, and pick the larger one.
There are O(n)-time complexity solutions to this problem, but these will only occur depending on the input of your array, as you can read in this article
You can perform this in 1 pass by storing largest elements from array A to to array of 3 say B.
For each element n in array A if n is greater than any element in array B then replace array B element with array A element.
Finally multiply the 3 elements in resulting array. This is constant time. This may still be 3n since you are checking against array of 3 as well.
For negative it would be additional 2 elements which contain the smallest. So it may be 5n but still constant time

how to find the maximum subsequence sum in a circular linked list

I am aware of the maximum subarray sum problem and its O(n) algorithm. This questions modifies that problem by using a circular linked list:
Find the sequence of numbers in a circular linked list with maximum sum.
Now what if sum of all entries is zero?
To me, the only approach is to modify the array solution and have the algorithm loop around and start over at the beginning at the list once the first iteration is done. Then do the same thing for up to 2 times the entire list and find the max. The down side is that there might be many very tricky to handle if I do it this way, for example, if the list looks like:
2 - 2 - 2 - 2 back to front
Then it's very tricky to not include the same element twice
Is there a better algorithm?
Thanks!!
First of all, it doesn't matter if the datastructure is a linked list or an array, so I will use array for simplicity.
I don't really understand your algorithm, but it seems that you are going to do something like duplicate the array at the back of the original, and run the Kadane's algorithm on this doubled-array. This is a wrong approach, and a counter example has been given by #RanaldLam.
To solve it, we need to discuss it in three cases:
All negative. In this case, the maximum of the array is the answer, and an O(N) scan will do the job;
The maximum sub-array does not require a wrapping, for example a = {-1, 1, 2, -3}. In this case, a normal Kadane's algorithm will do the job, time complexity O(N);
The maximum sub-array requires a wrapping, for example a = {1, -10, 1}. Actually, this case implies another fact: since elements inside the maximum sub-array requires a wrapping, then the elements that are not inside the maximum sub-array does not require a wrapping. Therefore, as long as we know the sum of these non-contributing elements, we can calculate the correct sum of contributing elements by subtracting max_non_contributing_sum from total sum of the array.
But how to calculate max_non_contributing_sum in case 3? This is a bit tricky: since these non-contributing elements do not require wrapping, so we can simply invert the sign of every elements and run Kadane's algorithm on this inverted array, which requires O(N).
Finally, we should compare the sum of non-wrapping (case 2) and wrapping (case 3), the answer should be the bigger one.
As a summary, all cases require O(N), thus the total complexity of the algorithm is O(N).
Your absolutly right. There is no better algorithm.

logic for checking sequential order in decimal numbers using java

I want to check the sequential order of decimal numbers and find the missing number.
For eg: If i have 1.1.1, 1.1.3, 1.1.4, 2.1.1, 2.1.3, 2.1.2, 3, etc
Here i need to find the missing number 1.1.2 and also out of sequence 2.1.2. Kindly help me with logic.
This does sound suspiciously like homework but, here's some hints for the algorithm. For simplicity, not efficiency, try a 2-step approach.
You'll have to treat each value in your initial list as an ordered set of integers. That is the value 2.1.3 is, an ArrayList whose elements are 2, 1, 3.
First determine what's out of sequence - this catches the 2.1.2 value. Something's out of sequence when the value of any part of the n-th element of the list is greater than any part of the (n+1)-th element. Walk through the list of values comparing two at a time; breaking each element into an list of integers.
Second, sort the list and determine if there are gaps. Sorting would still need to treat each value as a set of integers. A gap in the sorted list would be defined as a change
of more than 1 in any part of the two values. Stop comparing 2 values when you find a gap and move onto the next 2 values to compare.

Categories