Algorithm to find min & max value of equation from an array - algorithm

I have an array of 8 int, 4 positive and 4 negative.
X [10,-2,30,-4,5,-20,8,-9]
Now, let
Evaluated = a-b+c-d+e-f+g-h
where a,b..h are unique values taken from X.
I need to ensure that
Case 1. Evaluated = closest to zero.
Case 2. List out the 5 greatest possibility by solving Evaluated.
I can find the maximum value by sorting the array and assigning the max values to a,c,e and g, and the minimum values b,d,f and h. but how to find the next 4 values?
There are 8! ways of solving this equation right?
What would be the best way of determining this solution?

Ensure that negative values get positive sign and positive values get negative sign. You will be getting smallest possible value. You don't even need to sort.
One simple way of doing is this...
Loop Each Element of X
if X[i] > 0 Then X[i] = -1 * X[i]
End Loop
Add all elements of X (yes just don't think about subtracting, just add)
The result sum is the smallest possible value.

Just choose a, c, e, g as the four smallest and the rest as the largest values.
Function Small in Excel might help you.

If I understand the question correctly, you have an array of eight numbers. You want to choose four of the numbers to add, and four to subtract in order to get the smallest possible result. I would proceed as follows:
Sort the array from smallest to largest. This article describes two ways to do this. In your example, the sorted array would have [-20, -9, -4, -2, 5, 8, 10, 30].
Add The first four values in the array.
Subtract The last four values.
This will give you the smallest result possible by adding four values and subtracting the remaining values in the array of eight.

Related

Finding pair with sum between 1 and 2

Given n positive real numbers, the task is to provide a YES or NO answer to the following question:
"Does there exist a pair of numbers x and y such that 1 <= x+y <= 2.
The obvious solution is to sort all the numbers which will take O(nlogn). Now, pair can be checked in O(n) time.
However, the question is expected to be solved in constant space and linear time. Any insights?
Only numbers between 0 and 2 are useful for participating in a winning pair. The others can be ignored.
Each such number x makes it possible to create a pair with one additional number from the list between 1-x and 2-x.
Compute and maintain the acceptable bounds as you progress through the list. There cannot be more than two intervals of acceptable next values at any given time, because all the intervals of acceptable next values are included between -1 and 2 and have width 1. Therefore the acceptable next values to complete a pair can be represented in constant space.
Answer YES as soon as a number appears from the list that is in one of the at most two intervals of acceptable next values. Answer NO if you get to the end of the list without encountering the situation.
Example: 0.1, 0.5, 2.0 …
When starting, the set of values that can appear and complete a pair is the empty set.
After reading 0.1, the set of values that would complete a pair if they appeared now is [0.9, 1.9].
0.5 does not belong to the set of values that can complete a pair. However, after reading it, values in [0.5, 1.5] can complete a pair. Since we already had the set [0.9, 1.9], the new set of values that can complete a pair is [0.5, 1.9].
2.0 does not belong to the set of values that can complete a pair. However, we can now read any value in [-1, 0] to complete a pair. The new set of values that can be read to complete a pair henceforth is [-1, 0] ∪ [0.5, 1.9].
and so on…
I like Pascal Cuoq's algorithm for this problem, which I think is a nice and elegant solution. I wanted to post a different approach here that gives a slightly different perspective on the solution.
First, here's the algorithm:
Make one pass over the input and keep track of the following: the smallest number between 1 and 2, the smallest number less than 1 the largest number less than 1/2, and the number of numbers between 1/2 and 1.
If the sum of the smallest number between 1 and 2 and the smallest number less than 1 is less than 2, output YES.
Otherwise, if there are at least two numbers between 1/2 and 1, output YES.
Otherwise, if there are no numbers between 1/2 and 1, output NO.
Otherwise, if the sum of the largest number less than 1/2 and the unique number in the array between 1/2 and 1 is greater than 1, output YES.
Otherwise, output NO.
Here's a proof of why this works. As Pascal noted, we only care about numbers in the range [0, 2); anything outside this range can't be part of something that sums up to between 1 and 2. We can do a case analysis to think about what the possible numbers in the sum could be.
First, it's possible that one of the numbers is in the range (1, 2). We can't have two numbers in this range, so the other number must be in the range [0, 1]. In that case, we can take the smallest number in the range [0, 1] and see what happens when we add it with the smallest number in the range (1, 2): if their sum is between 1 and 2, we're done; otherwise, no sum involving a number in the range (1, 2) can be part of the summation.
Otherwise, the summation must purely consist of numbers from the range [0, 1]. Notice that at least one of the numbers must be in the range [1/2, 1], since otherwise their sum can't be at least 1. Also note that the sum of any two numbers in this range will never exceed 2. In this case, if there are two numbers in the range [1/2, 1], their sum satisfies the condition and we're done. If there are 0 numbers in the range [1/2, 1], there is no solution. Otherwise, we can try adding the largest number in the range [0, 1/2) to the one number in the range [1/2, 1] and see if the sum is at least 1. If the answer is yes, we've got the pair; if not, the answer is no.
I definitely like Pascal's algorithm more than this one, but I thought I'd post this to show how a case analysis can be used here.
Hope this helps!

Find pairs of numbers of numbers in an array with all pairs giving the same sum

Suppose there is an array of size N (N is always even). Given all the elements of the array form a pair,which gives the same sum when added. Find the sum. This is definitely not homework. For example :
A = {1,4,3,2,5,6,8,7} . ans = 9 because { (1,8) , (2,7) , (3,6) , (4,5) } form pairs of sum 9.
There can be duplicates also.
B = {3,4,5,3,4,5}. ans = 8
What I have tried is
1) Sort the array = O(nlogn).
2) find the sum of min and max of the sorted array. This is the sum required because if it is anything other than these 2, there will be at least one pair which cant be formed with the same sum. Hope I am clear.
Now my question, can this be done in linear time somehow? Hashing the numbers directly wouldn't suffice because the "Sum" is not known beforehand.
Make an O(n)-time pass through the set of numbers to find the min and max and to put all the numbers into a hash-table. Compute the target sum t = max + min. Then make a second O(n)-time pass through the set of numbers; for the number x, compute y = t-x, look for y in the hash table, and if it's found, report the pair. Regarding duplications, you also could keep counts of numbers in the hash table.
Find the sum of the array, double it, and divide by N.

Given an array of integers, find the LARGEST number using the digits of the array such that it is divisible by 3

E.g.: Array: 4,3,0,1,5 {Assume all digits are >=0. Also each element in array correspond to a digit. i.e. each element on the array is between 0 and 9. }
In the above array, the largest number is: 5430 {using digits 5, 4, 3 and 0 from the array}
My Approach:
For divisibility by 3, we need the sum of digits to be divisible by 3.
So,
Step-1: Remove all the zeroes from the array.
Step-2: These zeroes will come at the end. {Since they dont affect the sum and we have to find the largest number}
Step-3: Find the subset of the elements of array (excluding zeroes) such that the number of digits is MAXIMUM and also that the sum of digits is MAXIMUM and the sum is divisible by 3.
STEP-4: The required digit consists of the digits in the above found set in decreasing order.
So, the main step is STEP-3 i.e. How to find the subset such that it contains MAXIMUM possible number of elements such that their sum is MAX and is divisible by 3 .
I was thinking, maybe Step-3 could be done by GREEDY CHOICE of taking all the elements and keep on removing the smallest element in the set till the sum is divisible by 3.
But i am not convinced that this GREEDY choice will work.
Please tell if my approach is correct.
If it is, then please suggest as to how to do Step-3 ?
Also, please suggest any other possible/efficient algorithm.
Observation: If you can get a number that is divisible by 3, you need to remove at most 2 numbers, to maintain optimal solution.
A simple O(n^2) solution will be to check all possibilities to remove 1 number, and if none is valid, check all pairs (There are O(n^2) of those).
EDIT:
O(n) solution: Create 3 buckets - bucket1, bucket2, bucket0. Each will denote the modulus 3 value of the numbers. Ignore bucket0 in the next algorithm.
Let the sum of the array be sum.
If sum % 3 ==0: we are done.
else if sum % 3 == 1:
if there is a number in bucket1 - chose the minimal
else: take 2 minimals from bucket 2
else if sum % 3 == 2
if there is a number in bucket2 - chose the minimal
else: take 2 minimals from bucket1
Note: You don't actually need the bucket, to achieve O(1) space - you need only the 2 minimal values from bucket1 and bucket2, since it is the only number we actually used from these buckets.
Example:
arr = { 3, 4, 0, 1, 5 }
bucket0 = {3,0} ; bucket1 = {4,1} bucket2 = { 5 }
sum = 13 ; sum %3 = 1
bucket1 is not empty - chose minimal from it (1), and remove it from the array.
result array = { 3, 4, 0, 5 }
proceed to STEP 4 "as planned"
Greedy choice definitely doesn't work: consider the set {5, 2, 1}. You'd remove the 1 first, but you should remove the 2.
I think you should work out the sum of the array modulo 3, which is either 0 (you're finished), or 1, or 2. Then you're looking to remove the minimal subset whose sum modulo 3 is 1 or 2.
I think that's fairly straightforward, so no real need for dynamic programming. Do it by removing one number with that modulus if possible, otherwise do it by removing two numbers with the other modulus. Once you know how many to remove, choose the smallest possible. You'll never need to remove three numbers.
You don't need to treat 0 specially, although if you're going to do that then you can further reduce the set under consideration in step 3 if you temporarily remove all 0, 3, 6, 9 from it.
Putting it all together, I would probably:
Sort the digits, descending.
Calculate the modulus. If 0, we're finished.
Try to remove a digit with that modulus, starting from the end. If successful, we're finished.
Remove two digits with negative-that-modulus, starting from the end. This always succeeds, so we're finished.
We might be left with an empty array (e.g. if the input is 1, 1), in which case the problem was impossible. Otherwise, the array contains the digits of our result.
Time complexity is O(n) provided that you do a counting sort in step 1. Which you certainly can since the values are digits.
What do you think about this:
first sort an array elements by value
sum up all numbers
- if sum's remainder after division by 3 is equal to 0, just return the sorted
array
- otherwise
- if sum of remainders after division by 3 of all the numbers is smaller
than the remainder of their sum, there is no solution
- otherwise
- if it's equal to 1, try to return the smallest number with remainder
equal to 1, or if no such, try two smallest with remainder equal to 2,
if no such two (I suppose it can happen), there's no solution
- if it's equal to 2, try to return the smallest number with remainder
equal to 2, or if no such, try two smallest with remainder equal to 1,
if no such two, there's no solution
first sort an array elements by remainder of division by 3 ascending
then each subset of equal remainder sort by value descending
First, this problem reduces to maximizing the number of elements selected such that their sum is divisible by 3.
Trivial: Select all numbers divisible by 3 (0,3,6,9).
Le a be the elements that leave 1 as remainder, b be the elements that leave 2 as remainder. If (|a|-|b|)%3 is 0, then select all elements from both a and b. If (|a|-|b|)%3 is 1, select all elements from b, and |a|-1 highest numbers from a. If the remainder is 2, then select all numbers from a, and |b|-1 highest numbers from b.
Once you have all the numbers, sort them in reverse order and concatenate. that is your answer.
Ultimately if n is the number of elements this algorithm returns a number that is al least n-1 digits long (except corner cases. see below).
NOTE: Take care of corner cases(i.e. what is |a|=0 or |b|=0 etc). (-1)%3 = 2 and (-2)%3 = 1 .
If m is the size of alphabet, and n is the number of elements, this my algorithm is O(m+n)
Sorting the data is unnecessary, since there are only ten different values.
Just count the number of zeroes, ones, twos etc. in O (n) if n digits are given.
Calculate the sum of all digits, check whether the remainder modulo 3 is 0, 1 or 2.
If the remainder is 1: Remove the first of the following which is possible (one of these is guaranteed to be possible): 1, 4, 7, 2+2, 2+5, 5+5, 2+8, 5+8, 8+8.
If the remainder is 2: Remove the first of the following which is possible (one of these is guaranteed to be possible): 2, 5, 8, 1+1, 1+4, 4+4, 1+7, 4+7, 7+7.
If there are no digits left then the problem cannot be solved. Otherwise, the solution is created by concatenating 9's, 8's, 7's, and so on as many as are remaining.
(Sorting n digits would take O (n log n). Unless of course you sort by counting how often each digit occurs and generating the sorted result according to these numbers).
Amit's answer has a tiny thing missing.
If bucket1 is not empty but it has a humongous value, lets say 79 and 97 and b2 is not empty as well and its 2 minimals are, say 2 and 5. Then in this case, when the modulus of the sum of all digits is 1, we should choose to remove 2 and 5 from bucket 2 instead of the minimal in bucket 1 to get the largest concatenated number.
Test case : 8 2 3 5 78 79
If we follow Amits and Steve's suggested method, largest number would be 878532 whereas the largest number possible divisble by 3 in this array is 879783
Solution would be to compare the appropriate bucket's smallest minimal with the concatenation of both the minimals of the other bucket and eliminate the smaller one.

equal k subsets algorithm

does anyone know a good and efficient algorithm for equal k subsets algorithm ? preferably c or c++ which could handle a 100 element vector maybe with a complexity and time estimation
ex. 9 element vector
x = {2,4,5,6,8,9,11,13,14}
i need to generate all k=3 disjoint subsets with sum = 24
the algorithm should check if there are k disjoint subsets each with sum of elements 24, and list them in ascending order(in subset and between subsets) or to see if the solution doesn't exists
Solutions
solution 1: {2 8 14} {4 9 11} {5 6 13}
solution 2: {2 9 13} {4 6 14} {5 8 11}
Thanks
Unfortunately the constrained k-subset problem is a hard problem ... and if you want to generate all such k-subsets, you have no choice but to evaluate many possible candidates.
There are a couple of optimizations you can perform to reduce the search space.
Given a domain x constaining integer values,
Given a positive integer target M,
Given a positive integer k size for the subset,
When x only contains positive integers, and given a upper bound M, remove all items from x larger than or equal to M. These can't possibly be part of the subset.
Similarly, for k > 1, a given M, and x containing positive integers, remove all items from x which are larger than M + min0 + min1 ... minK. Essentially, remove all of the large values which can't possibly be part of the subset since even when selecting small values they will results in a sum in excess of M.
You can also use the even/odd exclusion principle to pare down your search space. For instance, of k is odd and M is even, you know that the sum will either contain three even numbers or two odd and one even. You can use this information to reduce the search space by eliminating candidate values from x that could be part of the sum.
Sort the vector x - this allows you to rapidly exclude values that can't possibly be included in the sum.
Many of these optimizations (other than the even/odd exclusion) are no longer useful/valid when the vector x contains negative values. In this case, you pretty much have to do an exhaustive search.
As Jilles De Wit points out, if X contains negative numbers you could add the absolute value of the smallest value in X to each member of X. This would shift all values back into positive range - making some of the optimizations I describe above possible again. This requires, however, that you are able to accurately represent positive values in the enlarged range. One way to achieve this would be to internally use a wider type (say long instead of int) to perform the subset selection search. If you do this, however, remember to scale the results subsets back down by this same offset when you return your results.

question on array and number

i have one problem
for example we have array
int a[]=new int[]{a1,a2,a3,a4,..........an}:
task is fill the same array by elements which are not in the array
for example
a={1,3,4,5,6,7} should be filled by any numbers {2,8,9,12,13,90}or others but not by elements which are in array this must not be{1,12,13,14,110} because 1 is in the array a
thanks
Interesting problem.
If the array is of signed integers, I believe it is possible in O(n) time and O(1) space, with no overflows, assuming the length is small enough to permit such a thing to happen.
The basic idea is as follows:
We have n numbers. Now on dividing those numbers by n+1, we get n remainders. So atleast one of the remainders in {0,1,2, ..., n} must be missing (say r). We fill the array with numbers whose remainders are r.
First, we add a multiple of n+1 to all negative numbers to make them positive.
Next we walk the array and find the remainder of each number with n+1. If remainder is r, we set a[r] to be -a[r] if a[r] was positive. (If we encounter negative numbers when walking, we use the negated version when taking remainder).
We also have an extra int for remainder = n.
At the end, we walk the array again to see if there are any positive numbers (there will be one, or the extra int for remainder = n will be unset).
Once we have the remainder, it is easy to generate n numbers with that remainder. Of course we could always generate just one number and fill it with that, as the problem never said anything about unique numbers.
If the array was of unsigned integers, we could probably still do this with better book-keeping.
For instance we could try using the first n/logn integers as our bitarray to denote which remainders have been seen and use some extra O(1) integers to hold the numbers temporarily.
For eg, you do tmp = a[0], find remainder and set the appropriate bit of a[0] (after setting it to zero first). tmp = a[1], set bit etc. We will never overwrite a number before we need it to find its remainder.
Just get the highest and lowest number in the array, create a new array with elements from your lower bound value to n.
Obtaining the highest and lowest number can be done in the same loop.
Assuming 12,4,3,5,7,8,89, it'll detect 3 as the lowest, 89 as the highest value. It then creates a new array and fills it with 3..89; then discard the old array.

Resources