Sqrt(x)

Easy
Binary Search Math

Problem Description

Given a non-negative integer x, return the square root of x rounded down to the nearest integer.

The returned integer should be non-negative as well.

You must not use any built-in exponent function or operator.

Example 1:

Input: x = 4

Output: 2

Explanation: The square root of 4 is 2.

Example 2:

Input: x = 8

Output: 2

Explanation: The square root of 8 is 2.82842..., rounded down is 2.

Intuition

We need to find the largest integer k such that k² ≤ x.

Since the square root of x must be between 0 and x, we can use binary search to efficiently find the answer. For each mid value, we check if mid² is less than, equal to, or greater than x.

Key insight: The answer lies in a sorted range [0, x], making binary search perfect for this problem.

Visual Walkthrough

Let's find the square root of x = 8

Step 1: Initialize search range

left
0
...
4
...
right
8

mid = (0 + 8) / 2 = 4

Step 2: Check mid² = 16 > 8

16 > 8, so the answer is in the left half

left
0
...
right
3
...
4

mid = (0 + 3) / 2 = 1

Step 3: Check mid² = 1 < 8

1 < 8, so update result and search right half

0
...
left
2
...
right
3

result = 1 (potential answer)

Step 4: Check mid² = 6.25 < 8

mid = 2, 2² = 4 < 8, update result and search right

2
left=right
3

result = 2 (updated)

Final: Check 3² = 9 > 8

3² = 9 > 8, search ends. Return result = 2

sqrt(8) = 2

Solution

class Solution:
    def mySqrt(self, x: int) -> int:
        # Handle edge cases
        if x == 0:
            return 0

        # Binary search in range [1, x]
        left, right = 1, x
        result = 0

        while left <= right:
            mid = left + (right - left) // 2

            # Check if mid is a valid square root
            if mid * mid == x:
                return mid
            elif mid * mid < x:
                result = mid       # Store potential answer
                left = mid + 1   # Search right half
            else:
                right = mid - 1  # Search left half

        return result
class Solution {
    public int mySqrt(int x) {
        // Handle edge case
        if (x == 0) {
            return 0;
        }

        // Binary search in range [1, x]
        int left = 1, right = x;
        int result = 0;

        while (left <= right) {
            int mid = left + (right - left) / 2;

            // Use division to avoid overflow
            if (mid <= x / mid) {
                result = mid;         // Store potential answer
                left = mid + 1;       // Search right half
            } else {
                right = mid - 1;      // Search left half
            }
        }

        return result;
    }
}
class Solution {
public:
    int mySqrt(int x) {
        // Handle edge case
        if (x == 0) {
            return 0;
        }

        // Binary search in range [1, x]
        int left = 1, right = x;
        int result = 0;

        while (left <= right) {
            long long mid = left + (right - left) / 2;

            if (mid * mid == x) {
                return mid;
            } else if (mid * mid < x) {
                result = mid;         // Store potential answer
                left = mid + 1;       // Search right half
            } else {
                right = mid - 1;      // Search left half
            }
        }

        return result;
    }
};

Important: Overflow Prevention

Watch out for overflow! When computing mid * mid, the product can exceed the maximum integer value for large inputs.

Solutions:

  • Use long long (C++) or long (Java) for mid
  • Rearrange the comparison: instead of mid * mid > x, use mid > x / mid

Complexity Analysis

Time Complexity: O(log n)

Binary search halves the search space with each iteration. For input x, we need at most log₂(x) iterations to find the answer.

Space Complexity: O(1)

We only use a constant amount of extra space for variables (left, right, mid, result), regardless of input size.

Alternative: Newton's Method

Newton's method converges much faster than binary search. Starting with an initial guess, we iteratively improve it using:

xnew = (xold + n / xold) / 2
def mySqrt(self, x):
    if x == 0:
        return 0
    r = x
    while r * r > x:
        r = (r + x // r) // 2
    return r

This method converges in O(log log n) iterations, making it even faster than binary search for very large numbers.

Related Problems