Найдите квадратный корень числа с помощью Bit Manipulation

Опубликовано: 19 Сентября, 2022

Учитывая неотрицательное целое число N , задача состоит в том, чтобы найти квадратный корень из N , используя побитовые операции. Если целое число не является полным квадратом, вернуть наибольшее целое число, которое меньше или равно квадратному корню из N , т. е. floor( √N ).

Примеры:

Input: N = 36
Output: 6
Explanation:  The square root of 36 is 6.

Input: N = 19
Output: 4
Explanation:  The square root of 19 lies in between
4 and 5 so floor of the square root is 4.

Подход: Чтобы решить проблему с помощью побитовых операторов, следуйте следующей идее:

Let’s assume that square root of N is X i.e., NX2
Let’s consider binary representation of X = ( bm, bm-1, ….., b2, b1, b0 ) where bi represents the ith bit in binary representation of X. Since, the value of each bits can either be 1 or 0, we can represent 
X = ( am + am-1 + . . . + a2 + a1 + a0 ) where ai = 2i or ai = 0.

Consider an approximate solution:
Sj = ( am + am-1 + . . . + aj ) and also let Sj = Sj+1 + 2j
If Sj2 ≤ X2 ≤ N then jth bit is set and 2j is part of the answer. Otherwise, it is 0.

Следуйте приведенной ниже иллюстрации для лучшего понимания.

Иллюстрации:

N = 36  , result = 0
Binary representation of N: 100100
MSB of N is 5.

Initially result = 0, a = 25 = 32

For 5th bit:
    =>(result + a) = (0 + 32) = 32, and 32 * 32 = 1024 is greater than N (36)
    => update a = a/2 = 32/2 = 16, result = 0

For 4th bit:
    => Now, (result + a) = 16, and 16 * 16 = 256 is greater than N (36)
    => update a = a/2 = 16/2 = 8

For 3rd bit:
    => Now, (result + a) = 8, and 8 * 8 = 64 is greater than N (36)
    => update a = a/2 = 8/2 = 4

For 2nd bit:
    => Now, (result + a) = 4, and 4 * 4 = 16 is less than N (36) so add (a) to result 
    => update a = a/2 = 4/2 = 2, result = 4

For 1st bit:
    => Now, (result + a) = (4+2) =6, and 6 * 6 = 36 is equal to N (36) so add (a) to result
    => update a = a/2 = 2/2 = 1, result = 6

So, the final result = 6.

Основываясь на приведенном выше наблюдении в каждой битовой позиции, найдите вклад этого бита в ответ и добавьте это значение к окончательному ответу. Выполните шаги, указанные ниже, чтобы реализовать описанный выше подход:

  • Инициализируйте переменную (скажем, результат ), чтобы сохранить окончательный ответ.
  • Начните итерацию с MSB N :
    • Если квадрат ( результат + a i ) не превышает N , то этот бит имеет вклад в результат [где a i равно 2 i ].
    • Поэтому добавьте значение a i в результат .
  • После завершения итерации значение, сохраненное в результате , является требуемым ответом.

Ниже приведена реализация вышеуказанного подхода:

Временная сложность: O (log N)
Вспомогательное пространство: O(1)