EasyBinary Search

Sqrt(x) โ€” Solution

Problem

Given a non-negative integer, find its integer square root โ€” the largest integer whose square does not exceed the input. No floating-point math is needed; you only return the whole-number part.

  • Input: x = 8
  • Output: 2
  • Explanation: โˆš8 โ‰ˆ 2.828, so we truncate to 2.

Counter-example: x = 9 โ†’ 3 (exact square root, no truncation).

Intuition

You're searching for the largest integer r such that r * r โ‰ค x. That's a classic binary search target: values below the answer satisfy the condition, values above don't โ€” a monotone boundary. Instead of checking every integer from 0 to โˆšx, you can halve the search space each step and find the answer in O(log x).


Approach 1 โ€” Linear Scan

Step from 0 upward, advancing as long as the next integer still fits. Stop when squaring the next candidate would exceed x.

  1. Start answer at 0.
  2. Check whether (answer + 1)ยฒ is still โ‰ค x.
  3. If yes, increment answer.
  4. Repeat until the check fails, then return answer.
1def mySqrt(x: int) -> int:
2    answer = 0
3    while (answer + 1) * (answer + 1) <= x:
4        answer += 1
5    return answer

Time: O(โˆšx) โ€” we iterate roughly โˆšx times before the condition fails.
Space: O(1) โ€” only the running counter.


Approach 2 โ€” Binary Search

Search in the range [0, x] for the largest integer whose square is โ‰ค x. Each iteration eliminates half the remaining candidates.

  1. Initialize left = 0, right = x.
  2. Compute mid = left + (right - left) / 2 to avoid overflow.
  3. If mid * mid == x, return mid immediately.
  4. If mid * mid < x, the answer is at least mid โ€” move left = mid + 1.
  5. If mid * mid > x, the answer is below mid โ€” move right = mid - 1.
  6. When the loop ends (left > right), right is the largest value confirmed to satisfy r * r โ‰ค x โ€” return it.
1def mySqrt(x: int) -> int:
2    left, right = 0, x
3    while left <= right:
4        mid = left + (right - left) // 2
5        if mid * mid == x:
6            return mid
7        elif mid * mid < x:
8            left = mid + 1
9        else:
10            right = mid - 1
11    return right  # right is the floor of sqrt(x) when loop exits

Time: O(log x) โ€” the search range halves each iteration.
Space: O(1) โ€” only a few pointers.


Complexity Summary

ApproachTimeSpaceWhen to use
Linear ScanO(โˆšx)O(1)Only for tiny inputs or when code simplicity is paramount
Binary SearchO(log x)O(1)General case โ€” standard for any "find the boundary" problem

Common Mistakes

  • Integer overflow in mid * mid: During early iterations, mid can be close to x itself (up to ~2 billion for max input). As an int, mid * mid overflows before the search narrows. Declare mid as long in Java or long long in C++; Python handles big integers natively.

  • Returning left instead of right after the loop: When binary search exits with left > right, it's right that holds the last index confirmed to satisfy r * r โ‰ค x. Returning left yields a value one too high for every non-perfect-square input.

  • Unsafe bounds when starting right = x / 2: Setting right = x / 2 is a valid optimization since โˆšx โ‰ค x / 2 for x โ‰ฅ 4, but it breaks for x = 0 and x = 1 where x / 2 = 0, making the answer 1 unreachable. Either start right = x or add an early return for x < 2.

  • Overflow in the linear scan's condition: Writing i * i <= x in Java/C++ overflows once i exceeds ~46341 on a 32-bit int. Use i <= x / i to avoid squaring, or cast to long/long long as shown above.

  • Returning ceiling instead of floor: It's easy to flip the binary search direction and accidentally return the smallest integer whose square is โ‰ฅ x. The floor requires keeping right = mid - 1 when too high, and returning right โ€” double-check the invariant against the example x = 8 โ†’ 2, not 3.


Related Problems

Ready to practice? Try it on SkillFlow

Adaptive problems, AI follow-up interviews, and a skill score that shows exactly where you need to improve.

Practice This Problem โ†’