LeetCode: Sqrt(x)
----- Условие ----- Требуется найти корень из числа. Если корень не целое число, то вернуть его целую часть.
----- Решение ----- Можно пройтись в цикле от нуля до первого подходящего числа, но тогда сложность алгоритма по времени составит квадратный корень из x. Есть более быстрое решение.
Используем бинарный поиск (по сути, у нас отсортированный массив от 0 до x). Два указателя каждую итерацию уменьшают количество подходящих чисел в 2 раза. Выходим из цикла, когда указатель на начало станет больше, чем указатель на конец.
Если мы не вышли из функции на строке if (mulRes === x) return midNum, значит, целого решения нет. На последней итерации, когда startNum равен endNum, startNum является ближайшим целым к корню из x. Если x больше, чем квадрат startNum (startNum “слева” от корня из x), то инкрементируем startNum, иначе он уже на нужной позиции (“справа” от корня из x). Возвращаем ближайшее “левое” значение, которое равно startNum - 1.
Сложность данного алгоритма по времени – O(log n), сложность по памяти – O(1).
----- Код ----- /** * @param {number} x * @return {number} */ const mySqrt = function(x) { if (x === 0) return 0;
let startNum = 0; let endNum = x;
while (startNum <= endNum) { const midNum = Math.trunc((endNum + startNum) / 2);
const mulRes = midNum * midNum;
if (mulRes === x) return midNum;
if (x > mulRes) { startNum = midNum + 1; } else { endNum = midNum - 1; } }
return startNum - 1; };