IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Leetcode 704 二分查找 -> 正文阅读

[数据结构与算法]Leetcode 704 二分查找

1.题目要求

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

2.思路分析

二分查找只有一个思想,那就是:逐步缩小搜索区间

在升序数组 nums 中寻找目标值 target,对于特定下标 i,比较 nums[i] 和 target 的大小:

  • 如果 nums[i]=target,则下标 i 即为要寻找的下标;

  • 如果 nums[i]>target,则 target 只可能在下标 i 的左侧;

  • 如果nums[i]<target,则 target 只可能在下标 i 的右侧。

不管是哪一种模板,都不会回答看到的 mid 的值以后如何设计条件,把区间进行正确的划分,以及:

  • 在某种条件下,mid 的值是否可以取到;
  • 下一轮搜索是在 mid 的左边还是右边继续查找。

3.代码实现

# 写法一:
class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left, right = 0, len(nums)
        # 在区间 nums[left..right] 里查找等于 target 的元素的下标
        # 退出循环的时候有 left == right 成立
        # 好处是:不用判断应该返回 left 还是 right;
        while left < right:
            mid = (left + right) // 2
            # 下一轮搜索区间是[left..mid]
            if nums[mid] > target:
                right = mid
            # 下一轮搜索区间是[mid+1..right]
            elif nums[mid] < target:
                left = mid + 1
            else:
                return mid
        return -1
    
# 写法二:
class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left, right = 0, len(nums)-1
        # # 在区间 nums[left..right] 里查找等于 target 的元素的下标
        while left <= right:
            mid = (left + right) // 2
            # 下一轮搜索区间是[left..mid-1]
            if nums[mid] > target:
                right = mid -1 
            # # 下一轮搜索区间是[mid+1..right]
            elif nums[mid] < target:
                left = mid + 1
            else:
                return mid
        return -1

4.复杂度分析

  • 时间复杂度:O(logn),其中 n 是数组的长度。
  • 空间复杂度:O(1)。

5.关于二分查找的疑问

1.为什么在题解里 while (left < right) 表示左闭右闭区间?

? while (left < right) 不表示搜索区间为「左闭右开」,这一点没有根据。真正应该看边界如何设置,这一点完全是人为定义。

? 表示一个区间,最直接的表示就是左闭右闭区间。例如:我们想表示搜索的范围是 1, 2, 3, 4, 5, 6, 7, 8, 9 ,很自然地会表示成 [1…9] ,我们也会说这些数是 1 到 9 之间的数,包括 1 和 9。正常情况下,不会说:这些数在 1 到 10 之间,不包括 10;

? 只看到 while (left < right) 里的 < ,不能说明右边界不能取到。真正看区间表示应该看左右边界到底如何设置,如果我们分析出下一轮搜索的范围是 [left…mid] 而设置 right = mid + 1,才表示搜索区间为「左闭右开」区间 。这是因为 [left…right) = [left…mid + 1) = [left…mid]。

  1. 为什么有一些二分查找取 mid 的时候,括号里要加 1?

? 因为 int mid = (left + right) / 2 在区间里有偶数个元素的时候,mid 只能取到位于左边的中间数,要想取到位于右边的中间数,就需要在括号里加 1。

为什么要取右边中间数呢?这是因为在区间里 只有 2 个元素的时候,把 [left…right] 划分成 [left…mid - 1] 和 [mid…right] 这两个区间,int mid = (left + right) / 2 这种取法不能把搜索区间缩小。

总之就是为了:避免死循环

  1. 什么时候 rightlen ?什么时候 right = len - 1

看题目,每个问题的答案都未必一样

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 19:31:09  更:2022-08-19 19:34:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 21:24:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码