I am given a list of integers/floats and I need to find the two numbers closest together. How would I do that using only nested for loops?
Checking each two points is not necessary and it's slow O(n^2).
I suggest to:
1) Sort the input.
2) Compare each two following values and choose smallest.
Timing will be much better O(n*log n) assuming that you use efficient sorting algorithm.
Code example:
input = [0, 65, 10, 100, 1231] #whatever you put here; it might be tuple, list, set, range, etc.
def find_closest(input):
sorted_input = sorted(input)
best = (sorted_input[-2], sorted_input[-1], sorted_input[-1] - sorted_input[-2])
for i, val in enumerate(sorted_input[:-1]):
d = sorted_input[i+1]-val
if d < best[2]:
best = (val, sorted_input[i+1], d)
return best
Function returns both values and distance between them.
If the points are one dimensional (as in your input is just a list of numbers like [1, 4, 6, 2]
), then you can easily do it in O(n log n) time by sorting them and finding the ones with the smallest difference:
def smallest_difference(points):
sorted_points = sorted(points)
return min(abs(prev - cur) for cur, prev in zip(sorted_points, sorted_points[1:]))
If you want to get the closest points instead of the distance between the closest points, use the key=
parameter of the min
function:
import operator
def smallest_difference(points):
sorted_points = sorted(points)
return min(zip(sorted_points, sorted_points[1:]), key=lambda x: abs(x[1] - x[0]))
If the points are two dimensional (as in your input is a list of 2 element tuples like [(1, 2), (3, 4), (5, 2)]
) then the Wikipedia article for this problem https://en.wikipedia.org/wiki/Closest_pair_of_points_problem describes how to extend this to two dimensions.
For each element, you have to compare the distance of it to each of the other elements with your previous "closest" value - any time this comparison yields smaller values, you remember that pair as the "two closest" ones.
So, it is straightforward:
def find_two_closest(numbers):
# most distant points:
delta = max(numbers), min(numbers)
for i, element in enumerate(numbers):
for j, sec_element in enumerate(numbers):
if i == j:
continue
if abs(sec_element - element) < abs(delta[0] - delta[1]):
delta = sec_element, element
return delta