Find the subset of an array such that the elements in the subset have a common difference - arrays

I came across a question while preparing for my interview.
Given an array of integers as input.
We have find a possible subset such that the elements in the array have a common difference.
For example,
Consider the input array to be {1,3,7,10,11}
Then the output should be {3,7,11}.
It is always that the elements in the array are in increasing order.
I thought of finding all the subsets and look for a solution.
But that would cause my program to run slower if the input array size is too large.
can anyone help me to crack this???

From what I understand, you want to extract possible subsets from an array such that each two consecutive numbers have the same difference value increasingly.
Here is my algorithm:
Remove duplicates.
Force arrange ascendingly.
Keep a hashtable with the difference values as keys and lists of lists as values.
Loop through the array, updating/adding a key in the hashtable that equals the difference between the two consecutive numbers at hand, and adding a list to the value (the list of lists) containing the two numbers.
After the loop, create an array. Loop through the hashtable, adding an element each time to the array which is an array itself: The merging of all nested lists in the value at hand. This is the array containing all possible subsets.
Here's a possible implementation in python:
from itertools import chain
def find_subsets (array):
table = dict()
last = array[-1]
for num in sorted (set (array), False)[1:]:
diff = last - num
table[diff].append([num, last])
last = num
return [list(chain(v)) for k, v in table]
Please try this code and correct it if wrong. I wrote this in a hurry.

Related

Getting 10 nsmallest arrays from a set of arrays

First of all, I apologize for the confusing title, the task which I'm trying to accomplish is itself still confusing to me, hence why I'm finding it hard to do it. I'll try to be as clear as I can from now on.
I have 100 500x500 arrays, the values inside range from 0 to 1. What I would like to do is write a code that gives me 10 arrays, these arrays will be a sort of composite of the minimum values between them.
The first array is made of the absolute minimum values, the second array with the 2nd order minimum values....and so on. So the 10 arrays will be a composite of sorted ascending values.
I managed to get the absolute minimum with np.minimum() but I have no clue on how to proceed to the next ones.
To reiterate, I don't want to sort the 100 arrays, but loop through them and create new arrays with the lowest values found in each position.
Sorting is the most efficient way.
np.sort([array0,array1,...], 0)
Will yield an array where the first element is an 100x100 array of the smallest element-wise entries of all your arrays, the second the second smallest, etc.

How to find most frequent triplet of integers?

I have a class containing 3 integers: r,g,b. I make table of 50 objects to that class. How to find most frequent triplet?
I made arrays of every value r,g,b. Then I sorted them and found most frequent value of each array.
Sort all your objects by RGB. Then just start at the beginning and count the duplicates.

Merge operation on two small unsorted arrays to produce one big sorted array

I was asked a question recently in an interview.
We are given an array A of size n+m with first n places filled with elements in random order (and m empty places at the end). Also, we have an array B with m elements in random order.
Write a merge function so that array A is filled with (n+m) elements in sorted order.
I was able to give a O((n+m)log(n+m)) solution.
Is there a better solution to this problem?
NO there's no better solution to that. Let t = max(m,n) then the complexity is O(tlog(t)). How do we go on to prove there's no better solution ?
Will if there was a better solution to this problem when nothing is known about the data, then given any array of size N (big enough), we could split it to n, m arrays and sort in less than Nlog(N).

Finding Median in Three Sorted Arrays in O(logn)

By googling for minutes, I know the basic idea.
Let A,B,and C be sorted arrays containing n elements.
Pick median in each array and call them medA, medB, and medC.
Without loss of generality, suppose that medA > medB > medC.
The elements bigger than medA in array A cannot become the median of three arrays. Likewise, the elements smaller than medC in array C cannot, so such elements will be ignored.
Repeat steps 2-4 recursively.
My question is, what is the base case?
Assuming a lot of base cases, I tested the algorithm by hands for hours, but I was not able to find a correct base case.
Also, the lengths of three arrays will become different every recursive step. Does step 4 work even if the length of three arrays are different?
This algorithm works for two sorted arrays of same sizes but not three. After the one iteration, you eliminates half of the elements in A and C but leaves B unchanged, so the number of elements in these arrays are no longer the same, and the method no longer apply. For arrays of different sizes, if you apply the same method, you will be removing different number of elements from the lower half and upper half, therefore the median of the remaining elements is not the same as the median of the original arrays.
That being said, you can modify the algorithm to eliminate same number of elements at both end in each iteration, this could be in efficient when some of the arrays are very small and some are very large. You can also turn this into a question of finding the k-th element, track the number of elements being throw away and change value of k at each iteration. Either way this is much trickier than the two array situation.
There is another post talking about a general case: Median of 5 sorted arrays
I think you can use the selection algorithm, slightly modified to handle more arrays.
You're looking for the median, which is the p=[n/2]th element.
Pick the median of the largest array, find for that value the splitting point in the other two arrays (binary search, log(n)). Now you know that the selected number is the kth (k = sum of the positions).
If k > p, discard elements in the 3 arrays above it, if smaller, below it (discarding can be implemented by maintaing lower and upper indexes for each array, separately). If it was smaller, also update p = p - k.
Repeat until k=p.
Oops, I think this is log(n)^2, let me think about it...

Way to judge if two Arrays are identical?

By identical I mean two Arrays contain same elements, order of elements in Arrays are not matter here.
The solution I came up with is like this(which turns out a wrong approach as pointed out in comments):
if the size of two Arrays are equal
See True, find all elements of Array A in Array B
All Found, find all elements of Array B in Array A
All Found, then I get conclusion two Arrays are identical
However, is there better algorithm in term of time complexity?
Let's say you have an User[] array 1 and User[] array 2. You can lop through array one and add them to Dictionary<User, int> dictionary where the key is the user and the value is a count. Then you loop through the second array and for each user in array 2 decrement the count in the dictionary (if count is greater than 1) or remove the element (if count is 1). If the user isn't in the dictionary, then you can stop, the arrays don't match.
If you get to the end and had previously checked length of the arrays is same, then the arrays match. If you hadn't checked length earlier (which of course you still should have), then you can just verify the dictionary is now empty after completely looping through array 2.
I don't know exactly what the performance of this is, but it will be faster than sorting both lists and looping through them comparing element by element. Takes more memory though, but if the arrays are not super large then memory usage shouldn't be an issue.
First, check the size of the two arrays. If they aren't equal then they don't contain the same elements.
After that, sort both the arrays in O(n lg(n)). Now, just check both the arrays element-by-element in O(n). As they are sorted, if they are equal then they will be equal in every position.
Your approach doesn't work, as it would treat [0, 1, 1] as being equal to [0, 0, 1]. Every item in A is in B and vice versa. You'd need to count the number of occurrences of each item in A and B. (You then don't need to do both, of course, if you've already checked the lengths.)
If the contents are sortable, you can sort both and then compare element-by-element, of course. That only works if you can provide a total ordering to elements though.
Sort both arrays according to a strict ordering and compare them term-by-term.
Update: Summarizing some of the points that have been raised, here the efficiency you can generally expect:
strict ordering available: O(log N) for sorting plus comparing term-by-term
equality and hash function available: compare hash counts term-by-term, plus actual object comparisons in the event of hash collisions.
only equality, no hashing available: must count each element or copy one container and remove (efficiency depends on the container).
The complexity of comparison term-by-term is linear in the position of the first mismatch.
My idea is to loop through the first array and look for items in the second array. The only issue of course is that you can't use an item in the second array twice. So, make a third array of booleans. This array indicates which items in array 2 'have been used'.
Loop through the first array. Inside that loop through each element in the second array to see if you can 'find' that element in the second array, but also check the third array to verify that the position in the second array hasn't been used. If you find a match update that position in the third array and move on.
You should only need to do this once. If you finish and you found a match for all items in array 2 then no unmatched items remain in array 2. You don't need to then loop through array 2 and see if array 1 contains the item.
Of course before you start all that check that the lengths are the same.
If you don't mind extra space you can do some like HashMap to Store the (element,count) pairs of the first array then check if the second array matches up; this would be linear in N (size of biggest array)
If the array sizes are identical and all of the elements in Array A are in Array B, then there is no need to verify that all of the elements in array B are in Array A. So at the very least you can omit that step.
EDIT: Depends on the definition of the problem. This solution would work if and only if his original solution would work, which it wouldn't if the arrays can have duplicate items and you weren't counting or marking them as "used."

Resources