Pair in sorted Array - arrays

How to make pairs of a sorted array such that the addition on the pairs after by multiplying of a pair is highest?
for example:
input array A[6,3,2,5]
output: (6 * 5)+(3 * 2)=36

You can achieve maximum product by multiplying the first two largest numbers. In the example you have given, A[6, 3, 2, 5]. The two largest number are 6 and 5. Therefore the maximum product that can be achieved by picking any two numbers from the array is 6*5 = 30.
I can help more if you may give more examples and show how to do the pairing in inputs of larger size. Describe your question a bit more.

Related

How to find Longest non-decreasing Subsequence containing duplicates in O(n) or O(nlogn)?

We know about an algorithm that will find the Longest Increasing subsequence in O(nlogn). I was wondering whether we can find the Longest non-decreasing subsequence with similar time complexity?
For example, consider an array : (4,10,4,8,9).
The longest increasing subsequence is (4,8,9).
And a longest non-decreasing subsequence would be (4,4,8,9).
First, here’s a “black box” approach that will let you find the longest nondecreasing subsequence using an off-the-shelf solver for longest increasing subsequences. Let’s take your sample array:
4, 10, 4, 8, 9
Now, imagine we transformed this array as follows by adding a tiny fraction to each number:
4.0, 10.1, 4.2, 8.3, 9.4
Changing the numbers this way will not change the results of any comparisons between two different integers, since the integer components have a larger magnitude difference than the values after the decimal point. However, if you compare the two 4s now, the latter 4 compares bigger than the previous one. If you now find the longest nondecreasing subsequence, you get back [4.0, 4.2, 8.3, 9.4], which you can then map back to [4, 4, 8, 9].
More generally, if you’re working with an array of n integer values, you can add i / n to each of the numbers, where i is its index, and you’ll be left with a sequence of distinct numbers. From there running a regular LIS algorithm will do the trick.
If you can’t work with fractions this way, you could alternatively multiply each number by n and then add in i, which also works.
On the other hand, suppose you have the code for a solver for LIS and want to convert it to one that solves the longest nondecreasing subsequence problem. The reasoning above shows that if you treat later copies of numbers as being “larger” than earlier copies, then you can just use a regular LIS. Given that, just read over the code for LIS and find spots where comparisons are made. When a comparison is made between two equal values, break the tie by considering the later appearance to be bigger than the earlier one.
I think the following will work in O(nlogn):
Scan the array from right to left, and for each element solve a subproblem of finding a longest subsequence starting from the given element of the array. E.g. if your array has indices from 0 to 4, then you start with the subarray [4,4] and check what's the longest sequence starting from 4, then you check subarray [3,4] and what's the longest subsequence starting from 3, next [2,4], and so on, until [0,4]. Finally, you choose the longest subsequence established in either of the steps.
For the last element (so subarray [4,4]) the longest sequence is always of length 1.
When in the next iteration you consider another element to the left (e.g., in the second step you consider the subarray [3,4], so the new element is element with the index 3 in the original array) you check if that element is not greater than some of the elements to its right. If so, you can take the result for some element from the right and add one.
For instance:
[4,4] -> longest sequence of length 1 (9)
[3,4] -> longest sequence of length 2 (8,9) 1+1 (you take the longest sequence from above which starts with 9 and add one to its length)
[2,4] -> longest sequence of length 3 (4,8,9) 2+1 (you take the longest sequence from above, i.e. (8,9), and add one to its length)
[1,4] -> longest sequence of length 1 (10) nothing to add to (10 is greater than all the elements to its right)
[0,4] -> longest sequence of length 4 (4,4,8,9) 3+1 (you take the longest sequence above, i.e. (4,8,9), and add one to its length)
The main issue is how to browse all the candidates to the right in logarithmic time. For that you keep a sorted map (a balanced binary tree). The keys are the already visited elements of the array. The values are the longest sequence lengths obtainable from that element. No need to store duplicates - among duplicate keys store the entry with largest value.

In Python , find the minimum product of two integers in an array/list, assuming that all values in the array/list are non-negative?

Write a Python program that has the following methods:
Given an array or list of unsorted integers, find the minimum product of two integers in an array/list, assuming that all values in the array/list are non-negative. For example, if the arr = [6, 3, 8, 2, 9] then the minimum product would be = 6, as 2 and 3 are the smallest integers in this given array and hence their product will be the answer. To solve this problem, the following idea can be used:
Answer the following question:
a) One of the solutions is to : "Consider every pair in the given array and return the Minimum product.
Just sort the list and return the product of the first 2 elements in the sorted list.
def minProduct(list):
sorted_list = list.sort()
return sorted_list[0] * sorted_list[1]
I'm sure a faster method would be to specifically find the 2 smallest values in the list, but this is a nice simple way.

Find way to separate array so each subarrays sum is less or equal to a number

I have a mathematical/algorithmic problem here.
Given an array of numbers, find a way to separate it to 5 subarrays, so that sum of each subarrays is less than or equal to a given number. All numbers from the initial array, must go to one of the subarrays, and be part of one sum.
So the input to the algorithm would be:
d - representing the number that each subarrays sum has to be less or equal
A - representing the array of numbers that will be separated to different subarrays, and will be part of one sum
Algorithm complexity must be polynomial.
Thank you.
If by "subarray" you mean "subset" as opposed to "contiguous slice", it is impossible to find a polynomial time algorithm for this problem (unless P = NP). The Partition Problem is to partition a list of numbers into to sets such that the sum of both sets are equal. It is known to be NP-complete. The partition problem can be reduced to your problem as follows:
Suppose that x1, ..., x_n are positive numbers that you want to partition into 2 sets such that their sums are equal. Let d be this common sum (which would be the sum of the xi divided by 2). extend x_i to an array, A, of size n+3 by adding three copies of d. Clearly the only way to partition A into 5 subarrays so that the sum of each is less than or equal to d is if the sum of each actually equals d. This would in turn require 3 of the subarrays to have length 1, each consisting of the number d. The remaining 2 subarrays would be exactly a partition of the original n numbers.
On the other hand, if there are additional constraints on what the numbers are and/or the subarrays need to be, there might be a polynomial solution. But, if so, you should clearly spell out what there constraints are.
Set up of the problem:
d : the upper bound for the subarray
A : the initial array
Assuming A is not sorted.
(Heuristic)
Algorithm:
1.Sort A in ascending order using standard sorting algorithm->O(nlogn)
2.Check if the largest element of A is greater than d ->(constant)
if yes, no solution
if no, continue
3.Sum up all the element in A, denote S. Check if S/5 > d ->O(n)
if yes, no solution
if no, continue
4.Using greedy approach, create a new subarray Asi, add next biggest element aj in the sorted A to Asi so that the sum of Asi does not exceed d. Remove aj from sorted A ->O(n)
repeat step4 until either of the condition satisfied:
I.At creating subarray Asi, there are only 5-i element left
In this case, split the remaining element to individual subarray, done
II. i = 5. There are 5 subarray created.
The algorithm described above is bounded by O(nlogn) therefore in polynomial time.

Maximum Product of Three Numbers logic

'''
Given an integer array, find three numbers whose product is maximum and
output the maximum product.
Example 1:
Input: [1,2,3]
Output: 6
Example 2:
Input: [1,2,3,4]
Output: 24
Note:
The length of the given array will be in range [3,104] and all elements are
in the range [-1000, 1000]. Multiplication of any three numbers in the input
won't exceed the range of 32-bit signed integer.
'''
class Solution(object):
def maximumProduct(self, nums):
nums.sort()
if nums[0]<0 and nums[1]<0 and abs(nums[1])>=nums[-2]:
res=nums[0]*nums[1]*nums[-1]
else:
res=nums[-1]*nums[-2]*nums[-3]
return res
My thought is if the absolute value of the smallest 2 negative numbers are bigger then the 2nd largest positive, those negative numbers should be used in the calc. otherwise, should be the product of the largest 3 nums. Could anyone please take a look and see where of the logic is wrong please?
There are three possibilities here:
the product of the three largest positive numbers,
the product of the largest positive number with the two smallest negative numbers,
the product of the three largest non-positive numbers, if there are no positive numbers in the list. For example, the answer for [-5, -4, -3, -2, -1] is -3 * -2 * -1 = -6.
You do not check for possibility #3 so your routine will sometimes fail.
Also, to distinguish between #1 and #2 you check if the product of the two smallest negative numbers (nums[0] * nums[1] if they are both negative) is larger than the product of the second and third largest numbers (nums[-3] * nums[-2] if they are both positive). Of course you need to do the checking that there are three positive values, etc. You also need to be careful of the edge case where one or more of the interesting values is zero.
Note that you can reduce all three of my possibilities to just this:
nums.sort()
return max(nums[-3] * nums[-2] * nums[-1], nums[0] * nums[1] * nums[-1])
You could reduce the overall time complexity of the algorithm by replacing the sort() with finding the two smallest and three largest values in the array, but with your array size at most 104 that is not a concern here.
May be using itertools.combination() to generate all three possible combination and next check the product of each combination.
import itertools
def prod(iterable): #use this funct as the built-in sum()
x = 1
for item in iterable:
x *= item
return x
comb = list(itertools.combinations(array, 3))
results= []
for item in comb:
results.append(prod(item))
print(max(results))

randomize sequence of array elements [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Is this C implementation of Fisher-Yates shuffle correct?
In order to simulate different order of input sequence into my application, I would like to generate a list of randomize sequence for an array input. For example, given an arr[10], the default sequence is 0,1,..,8,9. However, I'd like to manipulate the sequence into random order, for eg, 2,4,5,1,9,0,3,7,8,6.
I think rand() will generate a random value between 0-9, but it doesn't assure that each element is generated at least once. In such case, I am thinking about below pseudo, but is there a better way to generate random input sequence, and assure each number within the given range is generated at least once?
round #1:
generate a random number within 0-9.
let say 2 is selected
round #2:
generate a random number within 0-1
generate a random number within 3-9
let say 0 and 4 are selected
round #3:
generate a random number within 1
generate a random number within 3
generate a random number within 5-9
let say 1, 3, 7 are selected
round #4:
generate a random number within 5-6
generate a random number within 8-9
continue until 10 numbers are selected
Look at Fisher-Yates shuffle algorithm here for your requirement.
Here is another approach:
Create array of 10 elements and fill it with the values you want to randomize (0, 1, ..., 9).
Iterate for k from 9 down to 0 and pick a random number index = rand(k).
Swap the element at position k with the element at position index.
At the end your array will contain a random permutation of the original values, which is exactly what you wanted.

Resources