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
Related
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
For a given odd number n I want to efficiently compute 3 primes whose sum is equal to n. If there are multiple solutions then I want the one with the smallest primes (I want 2+2+17=21 instead of 3+5+13=21)
This is always possible forn>5.
My current approach is to reduce the problem to computing 2 primes whose sum is equal to n-3 and then I simply output the 2 computed primes and 3 since they obviously sum up to n. I choose 3 since it is the smallest odd prime and when I subtract it from n I get an even number, therefore it should be part of every solution I'm looking for. I'm using this to compute the sum of 2 primes, it works if n is even which it is in my case (since I subtracted 3 from an odd n).
My approach doesn't work since there are solutions without a 3 as a summand (41=2+2+37).
Is there a straightforward approach which I'm missing?
First test whether n-4 is prime. If so, your answer is {2, 2, n-4}. Otherwise, your original approach will work. You'll never use just one 2 because your sum would be even.
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.
I already know how to calculate the median, mean, mode from an array in Java. But is there actually a way to do the reverse like creating an array from the median, mode, mean, given the range and the number of numbers in the array ?
The numbers in the array can be created by randomness as long as it satisfies the condition above. It can stop when successfully find the first array with that condition. And plus the range can be from 0 to 10 or 0 to 100, not so much.
Yes / No
When you do an array to mmm, you are applying a lossy algorithm, you are losing the original data.
There can be literally an infinite number of array combinations that would result in the same mmm.
Some naive ideas
Median: for example your array have 2n+1 elements, put n elements which are less than your median, n elements which are greater than median;
Mean: say your array have m elements, Sum = m * Mean, generate m elements by partitioning Sum;
Mode: count the frequency of the numbers you put into the array, make sure Mode has the highest frequency;
ive been trying to the problem and have become stuck. The specification of the problem is a as follows
Median of k numbers is defined as the (k/2)th
smallest number if k is even; and the ((k+1)/2)th
smallest number if k is
odd. For example, median of the 4 numbers: 2 1 8 7 is the 2nd smallest number i.e. 2, and the median of the 5
numbers: 2 1 8 7 6 is the 3rd smallest number i.e. 6.
In this problem, you'll be given N numbers. Let the kth
median or m(k) be defined as the median of the first k
numbers (1<=k<=N). i.e. the 5th
median or m(5) is the median of the first 5 numbers, the 8th
median or m(8) is the
median of the first 8 numbers, etc. In other words, let Ai
denote the ith
number, then the kth
median or m(k) is
defined as the median of the numbers A1, A2, …, Ak.
Your task is to find m(1) + m(2) + m(3) + ...+ m(n), output the sum modulo 100000
so basically you have to read in numbers, first number is stored in the variable N and dictates how many numbers to be read in after that point is. (this is always 5). Then you must iterate through the reading in of the numbers, storing them in array, then sorting them and then finding the median of the median and then store the value in the and repeating until all numbers have been read in, sorted and median found.
I have managed to read the numbers in fine and i am able to sort them to some degree but my sorting algorithm, sorts them highest values first and smallest values last and in order to get the program to run properly to get the desired output i need it to be the other way round and i cant work out how.
The numbers read in will be like so
5
10
5
1
2
15
and the answer would be 27.
This is my code
Any help on this problem would be amazing because im just going round in cirles, btw the System.out.println(myIntArray [4]) etc is just a tracer to see how the sorting is taking place
You seem to be sorting the entire array each time through. You need to sort from 0 to i (exclusive) at each iteration. Also, for odd length, you need parentheses when computing the subscript: myIntArray[(i+1)/2] instead of myIntArray[i+1/2]. Because of operator precedence, Java will evaluate the latter as myIntArray[i+(1/2)], which is just myIntArray[i], since 1/2 is 0 in integer division.