Я считаю, что вы можете сделать это в O (1), используя непрерывные дроби. Любое рациональное число в диапазоне (0, 1] можно записать в виде
1 / (a0 + 1 / (a1 + 1 / (a2 + 1 / (... an))))
Кроме того, это представление обладает некоторыми замечательными свойствами. Для начала, если вы урежете представление в любой точке, вы получите очень хорошее приближение к рациональному числу. В частности, если вы просто урежете это представление на
1 / a0
Тогда доля a / b будет между 1 / a0 и 1 / (a0 + 1). Следовательно, если мы можем получить значение a0, то вы можете просто проверить два вышеуказанных числа, чтобы увидеть, какое из них ближе.
Вторым важным свойством является то, что существует отличный способ получить значение a0: оно определяется отношением b / a. Другими словами, вы можете найти ближайшую дробь следующим образом:
- Вычислить x = b / a, используя целочисленное деление.
- Проверьте, ближе ли 1 / x или 1 / (x + 1) к a / b, и выведите результат.
Если a и b вписываются в машинные слова, это выполняется за O (1) раз.