~/problems / Binary search / Binary search on the answer

Sqrt(x)

easy ~15 min

Write integer_sqrt(x: int) -> int that returns the largest whole number r with r * r <= x, the square root of x rounded down.

Work it out with integer arithmetic only: don't call math.isqrt, math.sqrt or any other square-root routine, and don't raise to the power 0.5. (At this size floating point isn't exact anyway: int((10**18 - 1) ** 0.5) gives 1000000000, one too many.)

integer_sqrt(8)                    # 2      (2 * 2 = 4 <= 8 < 9)
integer_sqrt(16)                   # 4
integer_sqrt(0)                    # 0
integer_sqrt(10**18)               # 1000000000
integer_sqrt(10**18 - 1)           # 999999999

Constraints: 0 <= x <= 10^18. A single test makes 20,000 calls with large x, so counting r up one at a time (up to a billion steps per call) is far too slow. Aim for O(log x) per call.

In C++ or Java, r * r overflows a 64-bit integer once r passes about 3 * 10^9, so keep candidates below that or compare r <= x / r instead.

Show hint

If r * r > x, every number above r is too big as well; if r * r <= x, every number below r works. So one comparison rules out a whole side of the range.

Topic: Binary search on the answer. Monotonic feasibility check + search the smallest value that works.

Read the visual guide
0:00
Ctrl ' run · Ctrl ↵ submit
esc