LeetCode 第69题:x的平方根

85 阅读3分钟

LeetCode 第69题:x的平方根

题目描述

给你一个非负整数 x ,计算并返回 x算术平方根

由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去

**注意:**不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5

难度

简单

题目链接

点击在LeetCode中查看题目

示例

示例 1:

输入:x = 4 输出:2 解释:4 的算术平方根是 2 ,因此返回 2 。

示例 2:

输入:x = 8 输出:2 解释:8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去,所以返回 2 。

提示

  • 0 <= x <= 2^31 - 1

解题思路

二分查找法

这道题可以使用二分查找来解决,因为平方根一定在0到x之间。

关键点:

  1. 使用二分查找缩小范围
  2. 注意整数溢出问题
  3. 处理边界情况
  4. 向下取整的处理

具体步骤:

  1. 处理特殊情况(0和1)
  2. 设定左右边界
  3. 使用二分查找逼近平方根
  4. 处理溢出和边界情况

图解思路

算法步骤分析表

步骤操作状态说明
初始x=8, left=1, right=8mid=44*4>8,缩小右边界
第1步left=1, right=4mid=22*2<8,记录答案
第2步left=3, right=4mid=33*3>8,结束
结果返回2-最后一个平方小于x的数

状态/情况分析表

情况输入输出说明
完全平方数164结果正好是整数
非完全平方数82需要向下取整
特殊情况0,10,1边界情况

代码实现

C# 实现

public class Solution {
    public int MySqrt(int x) {
        if (x == 0) return 0;
        if (x == 1) return 1;
        
        int left = 1;
        int right = x;
        int ans = 0;
        
        while (left <= right) {
            int mid = left + (right - left) / 2;
            
            // 使用除法避免溢出
            if (mid <= x / mid) {
                ans = mid;
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        
        return ans;
    }
}

Python 实现

class Solution:
    def mySqrt(self, x: int) -> int:
        if x <= 1:
            return x
        
        left = 1
        right = x
        ans = 0
        
        while left <= right:
            mid = left + (right - left) // 2
            
            # 使用除法避免溢出
            if mid <= x // mid:
                ans = mid
                left = mid + 1
            else:
                right = mid - 1
        
        return ans

C++ 实现

class Solution {
public:
    int mySqrt(int x) {
        if (x <= 1) return x;
        
        int left = 1;
        int right = x;
        int ans = 0;
        
        while (left <= right) {
            int mid = left + (right - left) / 2;
            
            // 使用除法避免溢出
            if (mid <= x / mid) {
                ans = mid;
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        
        return ans;
    }
};

执行结果

  • 执行用时:28 ms
  • 内存消耗:26.5 MB

代码亮点

  1. 🎯 使用二分查找优化性能
  2. 💡 巧妙避免整数溢出
  3. 🔍 特殊情况处理完善
  4. 🎨 代码简洁易懂

常见错误分析

  1. 🚫 整数溢出问题
  2. 🚫 边界条件处理错误
  3. 🚫 二分查找边界设置错误
  4. 🚫 结果向下取整处理错误

解法对比

解法时间复杂度空间复杂度优点缺点
二分查找O(log n)O(1)高效稳定需要处理溢出
牛顿迭代O(log n)O(1)收敛快实现复杂
暴力遍历O(√n)O(1)简单直观效率低

相关题目