Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding pairs with product greater than sum

Given as input, a sorted array of floats, I need to find the total number of pairs (i,j) such as A[i]*A[j]>=A[i]+A[j] for each i < j. I already know the naive solution, using a loop inside other loop, which will give me O(n^2) algorithm, but i was wondering if there is a more optimal solution.

like image 543
user2956907 Avatar asked Nov 07 '13 15:11

user2956907


People also ask

How do you find the pair of adjacent elements that has the largest product and return that product?

You can try to create a new array of length (arr. length-1) inside the function and append the products of adjacent numbers to this new array. Then find the largest number in the array and return it. This will solve the problem with negative product.

How do you find all pairs of elements in an array whose sum is equal to given number?

Follow the steps below to solve the given problem: Initialize the count variable with 0 which stores the result. Iterate arr and if the sum of ith and jth [i + 1…..n – 1] element is equal to sum i.e. arr[i] + arr[j] == sum, then increment the count variable. Return the count.

How do you find the number of pairs?

= n(n-1) / 2 which is our formula for the number of pairs needed in at least n statements.


2 Answers

Here's an O(n) algorithm.

Let's look at A * B >= A + B.

  • When A, B <= 0, it's always true.

  • When A, B >= 2, it's always true.

  • When A >= 1, B <= 1 (or B >= 1, A <= 1), it's always false.

  • When 0 < A < 1, B < 0 (or 0 < B < 1, A < 0), it can be either true or false.

  • When 1 < A < 2, B > 0 (or 1 < B < 2, A > 0), it can be either true or false.

Here's a visualization, courtesy of Wolfram Alpha and Geobits:

Now, onto the algorithm.

* To find the pairs where one number is between 0 and 1 or 1 and 2 I do something similar to what is done for the 3SUM problem.

* "Pick 2" here is referring to combinations.

  • Count all the pairs where both are negative

    Do a binary search to find the index of the first positive (> 0) number - O(log n).

    Since we have the index, we know how many numbers are negative / zero, we simply need to pick 2 of them, so that's amountNonPositive * (amountNonPositive-1) / 2 - O(1).

  • Find all the pairs where one is between 0 and 1

    Do a binary search to find the index of the last number < 1 - O(log n).

    Start from that index as the right index and the left-most element as the left index.

    Repeat this until the right index <= 0: (runs in O(n))

    • While the product is smaller than the sum, decrease the left index

    • Count all the elements greater than the left index

    • Decrease the right index

  • Find all the pairs where one is between 1 and 2

    Do a binary search to find the index of the first number > 1 - O(log n).

    Start from that index as the left index and the right-most element as the right index.

    Repeat this until the left index >= 2: (runs in O(n))

    • While the product is greater than the sum, decrease the right index

    • Count all the elements greater than the right index

    • Increase the left index

  • Count all the pairs with both numbers >= 2

    At the end of the last step, we're at the first index >= 2.

    Now, from there, we just need to pick 2 of all the remaining numbers,
    so it's again amountGreaterEqual2 * (amountGreaterEqual2-1) / 2 - O(1).

like image 109
Bernhard Barker Avatar answered Oct 26 '22 10:10

Bernhard Barker


You can find and print the pairs (in a shorthand form) in O(n log n).

For each A[i] there is a minimum number k that satisfies the condition(1). All values greater than k will also satisfy the condition.

Finding the lowest j such that A[j] >= k using binary search is O(log n).

So you can find and print the result like this:

(i, j)
(1, no match)
(2, no match)
(3, >=25)
(4, >=20)
(5, >=12)
(6, >6)
(7, >7)
...
(n-1, n)       

If you want to print all combinations, then it is O(n^2), because the number of combinations are O(n^2).

(*) To handle negative numbers it actually needs to be a bit more complex, because the numbers that satify the equation can be more that one range. I'm not absolutely sure how it behaves for small negative numbers, but if the number of ranges is not absolutely limited then my solution is no longer better than O(n^2).

like image 31
Klas Lindbäck Avatar answered Oct 26 '22 08:10

Klas Lindbäck