leetcode-二分查找-69 x 的平方根

这篇博客介绍了一个简单的算法实现,用于计算非负整数x的平方根。通过二分查找法,在区间[0, x/2](x等于1时区间为[0, x])内寻找目标值。在每次迭代中,计算中间点middle的平方,并根据结果调整搜索范围。当找到middle的平方等于x时,返回middle作为结果。这个算法的时间复杂度为O(logn),适用于求解整数的平方根问题。

69. x 的平方根

利用二分查找的思想,一般 x 的平方根都小于 x 的一般,因此二分查找范围:[0,x/2],对于 x==1的情况,则是[0,x],或者直接将 right 统一为 x/2+1;

然后判断中间点middle,如果(long)middle*middle(这里需要设置为 long 类型)等于 x,则直接返回 middle,若小于 x,则将左范围 left=middle( middle 可能为最终结果,因此middle 不能排除在搜索范围之外,这里需要注意防止 middle 永远为 left,即范围不缩小,因此求 middle 要求右中位数,即 middle=left+right+1>>1),若大于 x,则right=middle-1

难度简单644

实现 int sqrt(int x) 函数。

计算并返回 x 的平方根,其中 是非负整数。

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

示例 1:

输入: 4
输出: 2

示例 2:

输入: 8
输出: 2
说明: 8 的平方根是 2.82842..., 
     由于返回类型是整数,小数部分将被舍去。
class Solution {
    public int mySqrt(int x) {
        //int result=x<4?x:x/2;
        int left=0,right=x<4?x:x/2;
        while(left<right){
            int middle=left+right+1>>1;  //要指向右中位数,因为下面有 left=middle
            long t=(long)middle*middle;
            if(t==x){
                return middle;
            }else if(t>x){
                right=middle-1;
            }else left=middle;
            
        }
        return left;
        

    }
}

 

<think>首先,用户查询的是关于LeetCode平台上二分查找的相关内容,包括题目、解题思路和代码实现。系统指令要求我使用中文回答,结构清晰,逐步帮助用户解决问题,并保证回答真实可靠。 回顾提供的引用: - 引用[1]: 描述了一个简单的二分查找算法,用于查找插入位置,代码是Java。 - 引用[2]: 展示了二分查找的递归实现,语言是Python。 - 引用[3]: 提到了一个例题,涉及查找平方根,使用二分查找优化暴力查找。 - 引用[4]: 汇总了多个LeetCode二分查找题目,包括704题二分查找和另一个错误版本的问题。 - 引用[5]: 讲解了二分查找的基本思想和算法复杂度(O(log n))。 用户的问题是:“我想查找关于LeetCode平台上二分查找的相关内容,可能是题目、解题思路、代码实现等 请问LeetCode上的二分查找题目及解题方法”。我需要基于引用生成一个综合回答。 系统指令还要求在回答中引用的段落末尾自然地添加引用标识,如[^1]。由于引用是系统提供的,我必须正确引用它们。引用来自[1]到[5],所以我应该在相关部分标注引用标识。 此外,指令要求生成相关问题。在示例中,相关问题放在最后,以“§§相关问题§§”开头。所以我需要在回答结束后添加相关问题。 回答结构: - 开头介绍:简要解释二分查找及其在LeetCode上的应用。 - 核心部分:讨论LeetCode上的二分查找题目、解题思路和代码实现。 - 使用引用中的具体例子。 - 确保代码块格式正确,使用LaTeX语法。 - 行内数学表达式用$...$,独立公式用$$...$$。 - 结尾:总结,并添加相关问题。 关键点来自引用: - 二分查找的基本思想:分治策略,O(log n)时间复杂度。[^5] - 题目示例:704题(简单的二分查找)、查找插入位置、搜索插入位置、第一个错误版本、平方根查找等。 - 代码实现:迭代和递归版本(Java和Python)。 我需要组织内容: 1. **介绍二分查找**:简述定义、算法思想和重要性。[^5] 2. **LeetCode上常见的二分查找题目**: - LeetCode 704: 二分查找(经典问题)。[^4] - LeetCode 35: 搜索插入位置。[^1] - LeetCode 69: x 的平方根(使用二分查找优化)。[^3] - 其他,如第一个错误版本(LeetCode 278)。[^4] 3. **解题思路**: - 基本实现:迭代 vs. 递归。[^1][^2] - 关键点:边界条件、循环不变量、返回值。 4. **代码示例**: - 提供迭代和递归版本的代码,基于引用。 - 引用[1]的Java代码(搜索插入位置)。 - 引用[2]的Python递归代码。 - 引用[4]的二分查找基础代码(Java)。 - 必须格式化代码块。 5. **总结**:强调二分查找的应用和变种。 添加引用标识:在每个基于引用的段落末尾添加,例如解释完一个点后。 最后,生成相关问题: - 类似于示例,生成3-4个相关问题。 - 主题围绕二分查找的进一步学习、优化、应用等。 相关问题想法: 1. 二分查找LeetCode其他题目中的变种有哪些? 2. 如何避免二分查找中的常见错误,如边界问题? 3. 二分查找的性能分析,包括时间复杂度? 4. 二分查找在实际应用中的例子? 确保LaTeX语法: - 数学表达式如时间复杂度:$O(\log n)$ - 独立公式如果需要,但可能不需要太多。 回答语言:中文。 大纲回答: - 开头:二分查找的定义和重要性。 - 主体: - 常见题目介绍。 - 解题思路分析。 - 代码实现示例。 - 结尾:总结。 - 相关问题。 </think>以下是针对您的查询“LeetCode上的二分查找题目及解题方法”的详细解答。二分查找(Binary Search)是一种高效的分治算法,时间复杂度为 $O(\log n)$,广泛应用于有序数组的搜索问题[^5]。在LeetCode平台上,二分查找题目涵盖了基础查找、插入位置、边界条件优化等变种。我将基于LeetCode真题,逐步解释常见题目类型、解题思路和代码实现(参考了站内引用内容)。回答结构清晰,内容真实可靠,引用均来自LeetCode社区和算法知识库。 ### 1. **LeetCode常见的二分查找题目** LeetCode上有多个经典二分查找题目,主要分为基础查找和变种应用两类: - **基础查找类**:直接查找目标值的位置。 - **LeetCode 704: 二分查找**:在一个升序数组中查找目标值,返回其索引;若不存在,返回-1。这是最基础的二分查找问题[^4]。 - **LeetCode 35: 搜索插入位置**:在有序数组中查找目标值,若存在返回索引;若不存在,返回它将被插入的位置(即第一个大于目标值的索引)[^1]。 - **变种应用类**:二分查找用于解决特定边界或优化问题。 - **LeetCode 69: x 的平方根**:计算非负整数 x 的平方根(只保留整数部分),使用二分查找替代暴力搜索以提高效率[^3]。 - **LeetCode 278: 第一个错误的版本**:在版本序列中(已排序),查找第一个错误版本的位置,需处理边界条件[^4]。 这些题目共享核心思想:通过不断缩小区间(左指针 `left` 和右指针 `right`),高效定位目标值。解题关键是定义清晰的循环不变量(如区间一致性)和边界处理。 ### 2. **二分查找的解题思路** 二分查找的核心是分治策略:将数组分成两半,比较中间元素 `mid`,缩小搜索范围。解题步骤如下: 1. **初始化指针**:设 `left = 0`(数组起始索引),`right = length - 1`(数组结束索引)。 2. **循环条件**:通常使用 `while (left <= right)` 确保区间有效(当 `left > right` 时终止)。 3. **计算中间索引**:`mid = left + (right - left) // 2`。避免使用 `(left + right) // 2` 防止整数溢出[^1][^4]。 4. **比较与调整**: - 如果 `nums[mid] == target`,直接返回 `mid`。 - 如果 `nums[mid] > target`,说明目标在左半区,设 `right = mid - 1`。 - 如果 `nums[mid] < target`,说明目标在右半区,设 `left = mid + 1`。 5. **处理未找到情况**:循环结束后,根据题目要求返回(例如,在插入位置问题中返回 `left`)[^1][^5]。 变种题目的思路: - **插入位置问题(35题)**:当目标值不存在时,返回 `left` 指针位置,因为它代表第一个大于目标值的索引[^1]。 - **平方根问题(69题)**:将问题转化为在区间 `[0, x]` 中查找最大整数 `num`,使得 `num * num <= x`,使用二分查找代替线性搜索[^3]。 - **错误版本问题(278题)**:检查 `isBadVersion(mid)` 函数,调整指针以找到第一个错误版本。 时间复杂度始终为 $O(\log n)$,空间复杂度为 $O(1)$(迭代)或 $O(\log n)$(递归),适合大数据集[^5]。 ### 3. **代码实现示例** 以下是基于LeetCode题目和引用内容的代码实现。我提供迭代和递归两种版本(Java和Python),并添加注释说明关键点。 #### **迭代实现(LeetCode 704和35题的Java代码)** 引用[1]和[4]展示了迭代方法高效简洁。以下代码用于**LeetCode 704: 二分查找**(查找目标值索引): ```java class Solution { public int search(int[] nums, int target) { int left = 0; int right = nums.length - 1; // 循环条件:确保区间[left, right]有效 while (left <= right) { int mid = left + (right - left) / 2; // 避免溢出 if (nums[mid] == target) { return mid; // 找到目标值 } else if (nums[mid] > target) { right = mid - 1; // 目标在左半区 } else { left = mid + 1; // 目标在右半区 } } return -1; // 目标值不存在 } } ``` 对于**LeetCode 35: 搜索插入位置**(查找插入位置),代码修改返回值: ```java class Solution { public int searchInsert(int[] nums, int target) { int left = 0; int right = nums.length - 1; while (left <= right) { int mid = left + (right - left) / 2; if (nums[mid] == target) { return mid; } else if (nums[mid] > target) { right = mid - 1; } else { left = mid + 1; } } return left; // 插入位置:第一个大于目标值的索引 [^1] } } ``` #### **递归实现(LeetCode 704的Python代码)** 引用[2]提供了一个递归版本,便于理解分治思想。以下用于**LeetCode 704: 二分查找**: ```python class Solution: def search_recur(self, nums: List[int], low: int, high: int, target: int) -> int: if low > high: return -1 # 终止条件:区间无效 mid = low + (high - low) // 2 if nums[mid] == target: return mid elif nums[mid] > target: return self.search_recur(nums, low, mid - 1, target) # 搜索左半区 else: return self.search_recur(nums, mid + 1, high, target) # 搜索右半区 [^2] def search(self, nums: List[int], target: int) -> int: n = len(nums) low = 0 high = n - 1 return self.search_recur(nums, low, high, target) ``` #### **变种题目示例(LeetCode 69: x 的平方根)** 引用[3]讨论了该题的二分查找优化。以下Python代码实现: ```python class Solution: def mySqrt(self, x: int) -> int: if x == 0 or x == 1: return x left, right = 0, x while left <= right: mid = left + (right - left) // 2 sq = mid * mid if sq == x: return mid elif sq < x: left = mid + 1 else: right = mid - 1 return right # 返回最大整数满足 num*num <= x [^3] ``` ### 总结 二分查找LeetCode上常用于有序数组的搜索问题,核心是分治策略和指针调整。基础题如704和35题训练边界处理,变种题如69和278题拓展应用场景。所有实现强调时间复杂度 $O(\log n)$,适用于大数据集。通过练习这些题目,您能掌握算法的精髓。如需深入,可参考LeetCode官方题解或算法教材[^4][^5]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值