Length of list pattern - java

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.

Related

Factorial Combinations - Getting around list size limitation in Java

I have a rather interesting problem - I'm given an input list of points in 3d space and I'm required to output a collection of combinations of these points using the factorial combination equation below:
where n is the size of the input list of points, and r is the combination length.
For the output, I'm required to produce a list of lists with the sub-list containing the chosen points (size of each sublist being r, and the size of the parent list is the output of 'n choose r')
The problem is that given large enough values of n and r, I start running into the INTEGER.MAXVALUE size limitation for lists in java. E.g. having an input list size of 200 with an 'r' value of 5 will return a value of 2.5 billion - which is already above the max list size.
One way I've thought of to get around this is to split the input list into manageable chunks before I pass it to the combinatorial function:
// inputPoints is a List<Point> type
List<List<Point>> inputSplits = Helper.splitInputList(inputPoints) ; // splits input points list so that each subList is a maximum of say 100 in size.
List<List<List<Point>>> outputSplit;
for(var inputListSplit : inputListSplits){
outputSplit.Add(getCombinations(inputListSplit); // each result will be a List with size smaller than integer.MaxValue.
}
This can work but is inelegant. I've also thought of using linked lists (which apparently don't have a size limit) but haven't looked into the pros and cons of that just yet.
Are there any other ways this could be tackled ? I'm required to produce all possible combination outputs (they don't need to be ordered).
You can try a java.util.LinkedList, which has (in theory) limitless size.

Would it be efficient to sort with indexes

So I was thinking of a new sorting algorithm that might be efficient but I am not too sure about that.
1) Imagine we have an array a of only positive numbers.
2) We go through the array and find the biggest number n.
3) We create a new array b of the size n+1.
4) We go through every entry in the unsorted array and increase the value in the second array at the index of the number of the unsorted array we are looking at by one. (In pseudo-code this means: b[a[i]]++; while a[i] is the number we are currently looking at)
5) Once we have done this with every element in a, the array b stores at every index the exact amount of numbers of this index. (For example: b[0] = 3 means that we had 3 zeros in the initial array a)
6) We go through the whole array b and skip all the empty fields and create a new List or Array out of it.
So I can imagine that this algorithm can be very fast and efficient for smaller numbers only since at the end we have to go through the whole array b to build the sorted one, which is going to be really time consuming.
If we for example have an array a = {1000, 1} it would still check 1001 elements in array b wether or not they are 0 even though we only have 2 elements in the initial array.
With smaller numbers however we should almost get a O(n) result? I am not too sure about that and that's why I am asking you. Maybe I am even missing something really important. Thanks for your help in advance :)
Congratulations on independently re-discovering the counting sort.
This is indeed a very good sorting strategy for situations when the range is limited, and the number of items is significantly greater than the number of items in your array.
In situations when the range is greater than the number of items in the array a traditional sorting algorithm would give you better performance.
Algorithms of this kind are called pseudo-polynomial.
we should almost get a O(n) result
You get O(N+M) result, when M - max number in first array. Plus, you spend O(M) memory, so it have sense only if M is small. See counting sort

Partition array into K subsets of same sum value

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.

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.

Merging sorted arrays without using a sort function in Java

I have an assignment question that I need to solve without using a 'sort' commmand. I would appreciate any advice.
QUESTION: Suppose you have two arrays of ints, arr1 and arr2, each containing integers that are sorted in ascending order.
Write a static method named merge that recieves these two arrays a parameters and returns a reference to a new, sorted array of ints that is the result of merging the ints of arr and arr2.
Look into merge sort.
Pseudocode:
1: Set two pointers to beginning of the two arrays.
2: Compare the values from the two arrays at the pointers.
3: Add the smaller value to a new array and move its pointer to the next value in the array.
4: Repeat till both pointers cross the ends of the two arrays.
easy, this is the final step of the merge sort algorithm. make 2 integer variables to keep track of the index for each different input array.
Then loop through as many times as there are elements adding the minimum(or maximum depending on your sort order) out of the 2 first elements in the input arrays. This way on each iteration the smallest possible value is added to the return array. Just make sure to check that your first input array index is still less than the first input array length, if it is not then you know the rest of the elements to add are in the second input array. Increment the index for whichever array you took the element from, and increment your index for the overall array of values then.
If you need extra points or if you are bored: the relatively new Timsort algorithm uses a slightly improved merge function for the case where data is clustered (which is relatively common). This is documented in http://svn.python.org/projects/python/trunk/Objects/listsort.txt - search for "galloping mode". The galloping mode is also used in the Java implementation of timsort.

Categories