Sqrt(x)

Easy Top 250
Associated Patterns
Interviewed At (Company Tags)
GoogleAmazonMicrosoftMeta

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.

  • For example, do not use pow(x, 0.5) in C++ or x ** 0.5 in Python.

Examples

Example 1:

Input: x = 4 Output: 2 Explanation: The square root of 4 is 2, so we return 2.

Example 2:

Input: x = 8 Output: 2 Explanation: The square root of 8 is 2.82842…, and since we round it down to the nearest integer, 2 is returned.


Constraints

  • 0 <= x <= 2³¹ - 1

Halving the Square Roots Range

The square root of x must reside in the range [1, x]. We run binary search. Set left = 1 and right = x. At each step, calculate the midpoint mid = left + (right - left) / 2. Compare mid * mid with x:

  • If mid * mid == x, we have found the exact square root and return mid.
  • If mid * mid < x, mid is a potential candidate for the rounded-down result, so we record it and search the right half: left = mid + 1.
  • If mid * mid > x, mid is too large, so we search the left half: right = mid - 1.

Solution 1: Binary Search with Squared Comparison

Perform binary search over the integers range up to x, checking products.

class Solution {
    public int mySqrt(int x) {
        if (x == 0) return 0;
        int left = 1;
        int right = x;
        int ans = 0;

        while (left <= right) {
            int mid = left + (right - left) / 2;
            // Use division instead of multiplication to prevent integer overflow
            if (mid <= x / mid) {
                ans = mid; // record potential candidate
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return ans;
    }
}
class Solution:
    def mySqrt(self, x: int) -> int:
        if x == 0:
            return 0
        left = 1
        right = x
        ans = 0
        
        while left <= right:
            mid = left + (right - left) // 2
            # Avoid overflow by using division or Python's native arbitrary precision
            if mid <= x // mid:
                ans = mid  # record potential candidate
                left = mid + 1
            else:
                right = mid - 1
                
        return ans
class Solution {
public:
    int mySqrt(int x) {
        if (x == 0) return 0;
        int left = 1;
        int right = x;
        int ans = 0;

        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (mid <= x / mid) { // avoid integer overflow
                ans = mid;
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return ans;
    }
};

Complexity Analysis

  • Time Complexity: O(log x) since we halve the search range at each step.
  • Space Complexity: O(1) auxiliary space as we use a fixed number of variables.

Where It Breaks

If x is extremely large and exceeds standard double-precision float ranges (though constrained by x <= 2^31 - 1 here), floating-point division is required.


Common Mistakes

  • Integer Overflow: Using mid * mid <= x directly in Java or C++. If mid is large, mid * mid will overflow 32-bit registers, yielding negative numbers. Using mid <= x / mid prevents this overflow.
  • Not handling zero: Forgetting to return 0 immediately when x == 0, which can lead to a division by zero exception when x / mid executes at mid = 0.

Frequently Asked Questions

Why does mid <= x / mid prevent overflow? Mathematically, mid <= x / mid is equivalent to mid * mid <= x. Since division does not grow the numeric size, it is safe from register overflow limits.

Can we use Newton’s method instead? Yes. Newton’s method uses the update formula x_next = (x_curr + x / x_curr) / 2. It converges quadratically and is extremely fast, but binary search is simpler to implement.


← All Problems