'''
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))
Related
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.
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.
I've written a basic permutation program in C.
The user types a number, and it prints all the permutations of that number.
Basically, this is how it works (the main algorithm is the one used to find the next higher permutation):
int currentPerm = toAscending(num);
int lastPerm = toDescending(num);
int counter = 1;
printf("%d", currentPerm);
while (currentPerm != lastPerm)
{
counter++;
currentPerm = nextHigherPerm(currentPerm);
printf("%d", currentPerm);
}
However, when the number input includes repeated digits - duplicates - some permutations are not being generated, since they're duplicates. The counter shows a different number than it's supposed to - Instead of showing the factorial of the number of digits in the number, it shows a smaller number, of only unique permutations.
For example:
num = 1234567
counter = 5040 (!7 - all unique)
num = 1123456
counter = 2520
num = 1112345
counter = 840
I want to it to treat repeated/duplicated digits as if they were different - I don't want to generate only unique permutations - but rather generate all the permutations, regardless of whether they're repeated and duplicates of others.
Uhm... why not just calculate the factorial of the length of the input string then? ;)
I want to it to treat repeated/duplicated digits as if they were
different - I don't want to calculate only the number of unique
permutations.
If the only information that nextHigherPerm() uses is the number that's passed in, you're out of luck. Consider nextHigherPerm(122). How can the function know how many versions of 122 it has already seen? Should nextHigherPerm(122) return 122 or 212? There's no way to know unless you keep track of the current state of the generator separately.
When you have 3 letters for example ABC, you can make: ABC, ACB, BAC, BCA, CAB, CBA, 6 combinations (6!). If 2 of those letters repeat like AAB, you can make: AAB, ABA, BAA, IT IS NOT 3! so What is it? From where does it comes from? The real way to calculate it when a digit or letter is repeated is with combinations -> ( n k ) = n! / ( n! * ( n! - k! ) )
Let's make another illustrative example: AAAB, then the possible combinations are AAAB, AABA, ABAA, BAAA only four combinations, and if you calcualte them by the formula 4C3 = 4.
How is the correct procedure to generate all these lists:
Store the digits in an array. Example ABCD.
Set the 0 element of the array as the pivot element, and exclude it from the temp array. A {BCD}
Then as you want all the combinations (Even the repeated), move the elements of the temporal array to the right or left (However you like) until you reach the n element.
A{BCD}------------A{CDB}------------A{DBC}
Do the second step again but with the temp array.
A{B{CD}}------------A{C{DB}}------------A{D{BC}}
Do the third step again but inside the second temp array.
A{B{CD}}------------A{C{DB}}------------A{D{BC}}
A{B{DC}}------------A{C{BD}}------------A{D{CB}}
Go to the first array and move the array, BCDA, set B as pivot, and do this until you find all combinations.
Why not convert it to a string then treat your program like an anagram generator?
There's a similar question, I know, but it confused me, so I thought it easier to ask in my way.
So I have an array of values, positive and negative. The higher they are, the more probability they have of being chosen.
I'm having trouble actually figuring out how to assign the probabilities and then randomly choose one. I'm guessing the array will need to be sorted first, but then I'm a bit lost after that.
"I have various different sizes of cups of coffee. The larger they are, the more I want to charge for them. I'm having trouble actually figuring out how to assign prices".
This isn't just a programming problem - you've specified that probability increases with value, but you haven't said how it increases with value. Normally, coffee shops don't charge in direct proportion to the amount of coffee. You can't assign probabilities in proportion to value, because some of your values are negative, but probabilities cannot be negative.
Sounds like you need to nail down the problem a bit more before you can write any code.
If you really don't care how probability relates to value, other than that they increase in order of value, then one easy way would be:
sort your array
assign a probability of 1 to the first element, 2 to the second, and so on.
now, your probabilities don't add up to 1, which is a problem. So divide each probability by the total of all the probabilities you have assigned: (1 + 2 + .. + n) = n(n+1)/2. This is called "normalization".
Given your list of probabilities, which add up to 1, the easiest way to repeatedly choose one is generally to calculate the cumulative probabilities, which I will demonstrate with an example:
value (sorted): -12 -3 127 1000000
assigned probability: 0.1 0.2 0.3 0.4
cumulative probability: 0.1 0.3 0.6 1.0
The cumulative probability is defined as the sum of all the probabilities up to that point.
Now, from your random number generator you need a random (floating-point) value between 0 and 1. If it lies between 0 and 0.1, you've picked -12. If it lies between 0.1 and 0.3, you've picked -3, and so on. To figure out which range it lies in, you could walk linearly through your array, or you could do a binary search.
You could skip the normalization step and the use of floating-point, if you wanted. Assign "cumulative probabilities" (1, 3, 6, 10 ...) , but make it understood that the actual probability is the stored integer value divided by n(n+1)/2. Then choose a random integer from 0 to n(n+1)/2 - 1. If it's less than 1, you've selected the first value, else if less than 3 the second, and so on. This may or may not make the code clearer, and your RNG may or may not do well choosing integer values from a large range.
Note that you could have assigned probabilities (0.001, 0.002, 0.003, 0.994) instead of (0.1, 0.2, 0.3, 0.4), and still satisfied your requirement that "the higher the value, the higher the probability".
One way could be
Make all values positive (add absolute value of the minimum value to all values)
Normalize the values to sum to 1 (divide each value with the sum of the values)
To randomize a value from the generated distribution now you can
Pick random number on [0,1].
Start summing the probabilites until the sum is greater or equal to the random value. Choose that index as your random value.
Following up on Steve Jessop's suggestion, after you've chosen a random integer from 0 to n(n+1)/2 - 1, you can just get the triangular root: (-1 + sqrt((8*x)+1))/2
I'm working with permutations where each element is different from its original location. I would like an algorithm that given {an input length, row and digit}, will give me the output number. Here's an example:
If the input length is four, then all the permutations of 0123 are:
0123,0132,0213,0231,0312,0321,
1023,1032,1203,1230,1302,1320,
2013,2031,2103,2130,2301,2310,
3012,3021,3102,3120,3201,3210
The permutations in which no digit is in the same place (every digit has moved):
1032,1230,1302,
2031,2301,2310,
3012,3201,3210
Numbering starts at 0 so if the input to the function is {4,0,0}, the output should be the 0th (leftmost) digit of the 0th (first) permutation. First digit of 1032 is 1.
If the input is {4,1,1} then the output is the the second digit of 1230, which is 2.
The row number might be greater the nubmer of permutations. In that case, take the remainder modulo the number of permutations (in the above case, row modulo 9).
In the c language would be great.
(It's not homework, it's for work. Cuckoo hashing if you must know. I'd like to randomly select the swaps that I'll be making at each stage to see if it's better than BFS when the number of tables is greater than two.)
Why not just build a tree and iterate through it?
For example, if you have the digits 0123, then you know that the left most digit can be only from the set {1,2,3}. This would act as your first level in your tree.
Then, if you go down the path beginning with 1, you only have three options, {0, 2, 3}. If you go down the path beginning with 2 in the first level, you only have two options {0,3} (since you can't use 1 in the second digit from the left and the 2 was already used (you could pop the 2 from your list of choices)), etc.
The thing to watch out for in this approach is if you get to the end of a branch with 3 being your only option, in which case, you would just delete it.
For n > 10 generating all permutations and then filtering can become problematic. I think building out the tree would trim this significantly.
You can build the tree on the fly if need be. Your order can be defined by how you traverse the tree.
Brute-force approach in Python (you may use it to test your C implementation):
#!/usr/bin/env python
from itertools import ifilter, islice, permutations
def f(length, row, digit):
"""
>>> f(4, 0, 0)
1
>>> f(4, 1, 1)
2
"""
# 1. enumerate all permutations of range (range(3) -> [0,1,2], ..)
# 2. filter out permutations that have digits inplace
# 3. get n-th permutation (n -> row)
# 4. get n-th digit of the permutation (n -> digit)
return nth(ifilter(not_inplace, permutations(range(length))), row)[digit]
def not_inplace(indexes):
"""Return True if all indexes are not on their places.
"""
return all(i != d for i, d in enumerate(indexes))
def nth(iterable, n, default=None):
"""Return the nth item or a default value.
http://docs.python.org/library/itertools.html#recipes
"""
return next(islice(iterable, n, None), default)
if __name__=="__main__":
import doctest; doctest.testmod()