I was recently asked the following question, in a Foursquare interview. I was not able to code this.
We are given N points (xi,yi) where 1<=i<=N, and two numbers a and b,such that distance between two points (x1,y1) and (x2,y2) is max(a*|x1-x2|,b*|y1-y2|), how can we calculate sum of distances between each pair of points?
The number of points N is a high number.
Can anyone help with how to solve this question? Please explain the algorithm, other than the brute force one of traversing on all pairs of points.
This distance can be calculated by using the distance formula. The distance between two points ( x 1 , y 1 ) and ( x 2 , y 2 ) can be defined as d = ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 .
Distances in geometry are always positive, except when the points coincide. The distance from A to B is the same as the distance from B to A. In order to derive the formula for the distance between two points in the plane, we consider two points A(a,b) and B(c,d).
The Cartesian plane distance formula determines the distance between two coordinates. You'll use the following formula to determine the distance (d), or length of the line segment, between the given coordinates. d=√((x1-x2)2+(y1-y2)2)
Start by rescaling the axis, to get rid of a
and b
factors. Define x' = a * x, y' = b * y'
. Then the distance is:
max(a*|x1-x2|,b*|y1-y2|) =
max(|a*x1-a*x2|,|b*y1-b*y2|) =
max(|x'1-x'2|,|y'1-y'2|)
Secondly, rotate the coordinate system by 45 degrees, to change it to Taxicab geometry. Define s = (x' + y')/2, t = (x' - y')/2
. Then we have x' = s + t, y' = s - t
.
Then we can rewrite definition of the distance again:
max(|x'1-x'2|,|y'1-y'2|) =
max(|s1 + t1 - s2 - t2|,|s1 - t1 - s2 + t2|) =
max(|(s1 - s2) + (t1 - t2)|,|(s1 - s2) - (t1 - t2)|) =
|s1 - s2| + |t1 - t2|
-- last equation comes from the fact that max(|a + b|, |a - b|) = |a| + |b|
With this definition we can separately sum distances along s
axis and separately along t
axis and add the results.
Solving one-dimensional version of this problem is quite simple. You sort the points along the axis. Then each segment between (0-based) i
-th and i+1
-th point will contribute (i + 1) * (N - i - 1) * distance
. It's enough to sum these values.
Overall solution takes O(n lg n)
, since it need to sort points two times.
We want to compute
sum_i sum_j max(a |xi - xj|, b |yi - yj|).
Simplify the problem by mapping xi' = a xi
and yi' = b yi
and computing
sum_i sum_j max(|xi' - xj'|, |yi' - yj'|).
Simplify the problem by mapping ui = (xi + yi)/2
and vi = (xi - yi)/2
and computing
sum_i sum_j (|ui - uj| + |vi - vj|)
= sum_i sum_j |ui - uj| + sum_i sum_j |vi - vj|.
To solve the first subproblem in time O(n log n), here's some Python.
def one_d(us):
us = sorted(us)
return sum((2 * i - (len(us) - 1)) * u for (i, u) in enumerate(us))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With