1. 从暴力到二分:探索平方根算法的优化之路
今天我想和大家分享一道经典的面试题——计算非负整数x的平方根(向下取整)。这道题看似简单,却蕴含着算法优化的重要思想。作为面试中的高频题目,它考察的不仅是你对基础算法的掌握程度,更考验你从暴力解法逐步优化到高效算法的思考过程。
我在LeetCode上编号69的这道题上花费了不少时间,最初用暴力解法轻松通过,但看到讨论区普遍使用二分法后,我意识到自己算法思维上的不足。更让我困扰的是,虽然知道二分法的模板,但在实际应用中总是对边界条件的处理不够自信,需要反复试错。这促使我深入研究了二分查找的各种变体,下面就把我的学习心得和踩坑经验分享给大家。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 问题理解与暴力解法
2.1 问题定义解析
题目要求我们实现一个函数,对于给定的非负整数x,返回其平方根的整数部分。例如:
- 输入4,输出2
- 输入8,输出2(因为8的平方根约等于2.828,取整数部分)
这个问题的数学本质是找到最大的整数t,使得t² ≤ x。理解这一点非常重要,因为它直接决定了我们算法的终止条件。
2.2 暴力破解法实现
我最开始的解法非常直接——从0开始逐个尝试,直到找到满足条件的最大值:
java复制class Solution {
public int mySqrt(int x) {
int t = 0;
while((long)t*t <= x) {
t++;
}
return t-1;
}
}
这个解法的时间复杂度是O(√x),对于x=2147395600(接近Integer.MAX_VALUE)这样的极端情况,需要执行46340次循环。虽然能通过测试,但显然不是最优解。
注意:这里使用了(long)强制类型转换来避免整数溢出问题。这是暴力解法中容易被忽视但非常重要的细节。
3. 二分查找法深入剖析
3.1 为什么选择二分查找?
暴力法的效率问题促使我们寻找更优解。观察平方根函数的性质:
- 对于x≥0,√x的值域是单调非递减的
- 我们需要在一个有序范围内查找特定值
这正是二分查找大显身手的地方!二分法可以将时间复杂度从O(n)降到O(logn),对于大数计
