1

There is a popular algorithm problem known as Two Sum. For those who aren't aware of it, here's a quick description. You are given an array of numbers with n elements and a target number. You are supposed to find 2 numbers in the array such that they add up to the target number.

This problem can be found on Leetcode.

https://leetcode.com/problems/two-sum/

The numbers in the array are typically given as integers. Here's my question. How would one go about solving this problem if the array was filled with floating point numbers instead? This problem is more difficult because of rounding errors.

I recognize that this is a pretty general problem statement. For example, a solution to this problem will really depend on whether the target number is limited to integers or can be a float as well. I think in order for this problem to make sense, the target number must be limited to integers (correct me if I'm wrong). However, beyond that, what are general ideas/techniques that can be performed to handle rounding errors for this problem?

user3567004
  • 117
  • 1
  • 12
  • If you solve it using a hash-table, you might want to add some extra hashes. These could be the per entry two extra floats (next and previous float to listed float). This way you will overcome the rounding errors. [This question](https://stackoverflow.com/questions/11159774) might be handy – kvantour Sep 30 '19 at 15:37

1 Answers1

1

Finding Floating-Point Sum

If the problem is to find two array elements x and y such that their sum is the target number z when added with floating-point arithmetic, then the floating-point rounding issues are largely irrelevant.

An algorithm for the Two Sum problem is:

  1. Sort the elements. (To remember their original indices in the array, associate the elements with their indices and retain those associations while sorting.)
  2. Set L to point to the lowest element and H to point to the highest element.
  3. While L is earlier than H:
    • If the sum of *L (the number pointed to by L) and *H is z, stop. The desired elements are *L and *H.
    • If the sum is less than z, advance L.
    • If the sum is greater than z, decrease H.
  4. Stop. There is no solution.

Floating-point rounding is not a problem because floating-point addition is (weakly) monotonic: If the floating-point sum of x0 < x1, then the floating-point sum of x0 and y is less than or equal to the floating-point sum of x=1 and y. This means the test sum of *L and *H in the algorithm always correctly indicates whether L or H must be adjusted to continue the search—if the test sum is too low, then we need a higher number, so L must be advanced. Similarly, if the test sum is too high, H must be decreased. No solution can be missed this way.

Finding Real-Number Sum

If the problem is to find two array elements x and y such that there sum is the target number z when added with real-number arithmetic, then the above algorithm suffices with a simple modification to the test.

Replace step 3. above with:

  • Evaluate s = *L + *H; z = s - *L; t = *H - z; with floating-point arithmetic using round-to-nearest. Then, in real-number arithmetic, s + t is exactly *L + *H.1 s contains the most significant portion of the sum (the nearest value representable in floating-point), and t contains the error or deviation of s from the real-number sum of *L and *H. If s equals z and t equals zero, stop. The desired elements are *L and *H.
  • If s < z or s = z and t < 0, advance L.
  • Otherwise, decrease H.

Footnote

1 Muller et al, Handbook of Floating-Point Arithmetic, 2010, Theorem 4, pages 126-129.

Community
  • 1
  • 1
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • You might want to add a bit about using something like `target-*H` to check for false matches. – Sneftel Sep 30 '19 at 12:53
  • Fair enough. But since the OP doesn't specify that (and does mention handling rounding errors), it might be useful to mention the option. – Sneftel Sep 30 '19 at 12:58
  • What about cases where you want to reach 60, but your numbers are of the order of 1E20. How would you handle this? – kvantour Oct 01 '19 at 13:16
  • @kvantour: The algorithm works. How would the situation you ask about be any different than a list of integers where the target were 60 but the integers were on the order of 1,000,000? If there were no pair whose sum were 60, the algorithm would determine that. If there were a pair, the algorithm would find it. – Eric Postpischil Oct 01 '19 at 13:18
  • @Sneftel: It turns out testing for the real-number sum and modifying the algorithm to find an exact match is easy. I updated the answer. – Eric Postpischil Oct 03 '19 at 00:23