当前位置: 首页 > news >正文

二分查找题目:二分查找

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 前言
  • 解法一
    • 思路和算法
    • 代码
    • 复杂度分析
  • 解法二
    • 思路和算法
    • 代码
    • 复杂度分析
  • 拓展问题

题目

标题和出处

标题:二分查找

出处:704. 二分查找

难度

2 级

题目描述

要求

给定一个按升序排序的整数数组 nums \texttt{nums} nums 和一个整数 target \texttt{target} target,在 nums \texttt{nums} nums 中查找 target \texttt{target} target。如果 target \texttt{target} target 存在,返回其下标。否则,返回 -1 \texttt{-1} -1

要求时间复杂度是 O(log n) \texttt{O(log n)} O(log n)

示例

示例 1:

输入: nums = [-1,0,3,5,9,12], target = 9 \texttt{nums = [-1,0,3,5,9,12], target = 9} nums = [-1,0,3,5,9,12], target = 9
输出: 4 \texttt{4} 4
解释: 9 \texttt{9} 9 nums \texttt{nums} nums 中,下标为 4 \texttt{4} 4

示例 2:

输入: nums = [-1,0,3,5,9,12], target = 2 \texttt{nums = [-1,0,3,5,9,12], target = 2} nums = [-1,0,3,5,9,12], target = 2
输出: -1 \texttt{-1} -1
解释: 2 \texttt{2} 2 不在 nums \texttt{nums} nums 中,因此返回 -1 \texttt{-1} -1

数据范围

  • 1 ≤ nums.length ≤ 10 4 \texttt{1} \le \texttt{nums.length} \le \texttt{10}^\texttt{4} 1nums.length104
  • -10 4 < nums[i], target < 10 4 \texttt{-10}^\texttt{4} < \texttt{nums[i], target} < \texttt{10}^\texttt{4} -104<nums[i], target<104
  • nums \texttt{nums} nums 中的所有整数各不相同
  • nums \texttt{nums} nums 按升序排序

前言

这道题是最简单的二分查找。给定的数组按升序排序,所有的元素各不相同,因此如果目标值存在则其下标唯一。

low \textit{low} low high \textit{high} high 分别表示二分查找的下标范围的下界和上界,初始时 low \textit{low} low high \textit{high} high 分别为数组的最小下标和最大下标。每次查找时,取 mid \textit{mid} mid low \textit{low} low high \textit{high} high 的平均数向下取整,判断下标 mid \textit{mid} mid 处的数和目标值的大小关系,调整查找的下标范围。

  • 如果 nums [ mid ] = target \textit{nums}[\textit{mid}] = \textit{target} nums[mid]=target,则找到目标值,其下标为 mid \textit{mid} mid

  • 如果 nums [ mid ] > target \textit{nums}[\textit{mid}] > \textit{target} nums[mid]>target,则如果目标值存在,其下标一定小于 mid \textit{mid} mid,因此在下标范围 [ low , mid − 1 ] [\textit{low}, \textit{mid} - 1] [low,mid1] 中继续查找。

  • 如果 nums [ mid ] < target \textit{nums}[\textit{mid}] < \textit{target} nums[mid]<target,则如果目标值存在,其下标一定大于 mid \textit{mid} mid,因此在下标范围 [ mid + 1 , high ] [\textit{mid} + 1, \textit{high}] [mid+1,high] 中继续查找。

如果查找的过程中出现 low > high \textit{low} > \textit{high} low>high,则目标值不存在,返回 − 1 -1 1

每次查找都可以将查找的下标范围减少一半,因此当数组的长度是 n n n 时,二分查找的时间复杂度是 O ( log ⁡ n ) O(\log n) O(logn)

二分查找可以使用递归或迭代实现。

解法一

思路和算法

使用递归实现二分查找时,需要在递归调用时指定查找的下标范围。每次查找时,如果当前查找的下标处的元素值等于目标值则返回当前查找的下标,否则根据元素值与目标值的大小关系调整查找的下标范围,然后在新的下标范围中继续查找。

递归调用有以下两个终止条件。

  1. 如果当前的下标范围是空,即 low > high \textit{low} > \textit{high} low>high,则目标值不存在,返回 − 1 -1 1

  2. 如果当前查找的下标处的元素值等于目标值,则返回当前查找的下标。

代码

class Solution {public int search(int[] nums, int target) {return search(nums, target, 0, nums.length - 1);}public int search(int[] nums, int target, int low, int high) {if (low > high) {return -1;}int mid = low + (high - low) / 2;if (nums[mid] == target) {return mid;} else if (nums[mid] > target) {return search(nums, target, low, mid - 1);} else {return search(nums, target, mid + 1, high);}}
}

复杂度分析

  • 时间复杂度: O ( log ⁡ n ) O(\log n) O(logn),其中 n n n 是数组 nums \textit{nums} nums 的长度。二分查找的次数是 O ( log ⁡ n ) O(\log n) O(logn),每次查找的时间是 O ( 1 ) O(1) O(1),时间复杂度是 O ( log ⁡ n ) O(\log n) O(logn)

  • 空间复杂度: O ( log ⁡ n ) O(\log n) O(logn),其中 n n n 是数组 nums \textit{nums} nums 的长度。空间复杂度主要取决于递归调用栈空间,递归调用栈的层数是 O ( log ⁡ n ) O(\log n) O(logn)

解法二

思路和算法

使用迭代实现二分查找时,需要在二分查找的过程中维护查找的下标范围。每次查找时,如果当前查找的下标处的元素值等于目标值则返回当前查找的下标,否则根据元素值与目标值的大小关系调整查找的下标范围,然后在新的下标范围中继续查找。

查找的过程中,如果当前查找的下标处的元素值等于目标值,则返回当前查找的下标。如果出现 low > high \textit{low} > \textit{high} low>high,则目标值不存在,返回 − 1 -1 1

代码

class Solution {public int search(int[] nums, int target) {int low = 0, high = nums.length - 1;while (low <= high) {int mid = low + (high - low) / 2;if (nums[mid] == target) {return mid;} else if (nums[mid] > target) {high = mid - 1;} else {low = mid + 1;}}return -1;}
}

复杂度分析

  • 时间复杂度: O ( log ⁡ n ) O(\log n) O(logn),其中 n n n 是数组 nums \textit{nums} nums 的长度。二分查找的次数是 O ( log ⁡ n ) O(\log n) O(logn),每次查找的时间是 O ( 1 ) O(1) O(1),时间复杂度是 O ( log ⁡ n ) O(\log n) O(logn)

  • 空间复杂度: O ( 1 ) O(1) O(1)

拓展问题

最简单的二分查找中,如果目标值不存在则返回 − 1 -1 1。当目标值不存在时,定义目标值在数组中的插入位置如下:目标值 target \textit{target} target 在数组 nums \textit{nums} nums 中的插入位置是 index \textit{index} index,则 nums [ index − 1 ] < target < nums [ index ] \textit{nums}[\textit{index} - 1] < \textit{target} < \textit{nums}[\textit{index}] nums[index1]<target<nums[index]。这里假设 nums [ − 1 ] = − ∞ \textit{nums}[-1] = -\infty nums[1]= nums [ n ] = + ∞ \textit{nums}[n] = +\infty nums[n]=+,其中 n n n 是数组 nums \textit{nums} nums 的长度。

当目标值不存在时,是否可以使用返回值表示目标值在数组中的插入位置?

在二分查找的过程中,如果 nums [ mid ] < target \textit{nums}[\textit{mid}] < \textit{target} nums[mid]<target,则将 low \textit{low} low 更新为 mid + 1 \textit{mid} + 1 mid+1,因此在二分查找结束之后有 nums [ low ] ≥ target \textit{nums}[\textit{low}] \ge \textit{target} nums[low]target。当目标值不存在时,二分查找结束之后有 nums [ low ] > target \textit{nums}[\textit{low}] > \textit{target} nums[low]>target。又由于当 nums [ mid ] ≥ target \textit{nums}[\textit{mid}] \ge \textit{target} nums[mid]target 时不可能将 low \textit{low} low 更新为比 mid \textit{mid} mid 大的值,因此在二分查找结束之后有 nums [ low − 1 ] < target \textit{nums}[\textit{low} - 1] < \textit{target} nums[low1]<target

因此在二分查找结束之后有 nums [ low − 1 ] < target < nums [ low ] \textit{nums}[\textit{low} - 1] < \textit{target} < \textit{nums}[\textit{low}] nums[low1]<target<nums[low] low \textit{low} low 即为目标值在数组中的插入位置。

当目标值不存在时,为了使返回值同时能反映目标值不存在以及表示目标值在数组中的插入位置,返回值可以是 − low − 1 -\textit{low} - 1 low1

x x x 表示二分查找的返回值。当 x ≥ 0 x \ge 0 x0 时,目标值在数组中的下标 x x x 处;当 x < 0 x < 0 x<0 时,目标值不在数组中,插入位置是 − x − 1 -x - 1 x1


http://www.mrgr.cn/news/60473.html

相关文章:

  • 2024 Rust现代实用教程:1.2编译器与包管理工具以及开发环境搭建
  • MarkDown代码
  • 大厂面试真题-说一说LBCC
  • 数据挖掘(一)
  • 算法题总结(十九)——图论
  • 【SpringCloud】 K8s的滚动更新中明明已经下掉旧Pod,还是会把流量分到了不存活的节点
  • 【C++】继承与模板
  • vLLM推理部署Qwen2.5
  • 【云原生】云原生后端:数据管理
  • 有手就行的大模型教程:如何在个人电脑上部署盘古大模型
  • 2024最新保姆级Python下载安装教程
  • 小白也能轻松制作产品宣传册的软件
  • 消息队列-RabbitMQ
  • npcap-1.80
  • OpenIPC开源FPV之msposd配置
  • 本地搭建Trilium Notes轻松创建个人知识库并实现远程查看文档资料
  • 内衣洗衣机真的可以洗得更干净吗?入手这四款洗衣机真心不后悔!
  • 全家桶工具介绍
  • 10.28.2024刷华为OD C题型
  • 采购管理系统有哪些基础的功能
  • js中 没值用 ??还是||
  • DDRPHY数字IC后端设计实现系列专题
  • WebGL进阶(四)-视点和视线
  • JVM进阶调优系列(7)JVM调优监控必备命令、工具集合|实用干货
  • react18中react-thunk实现公共数据仓库的异步操作
  • WSGI、uwsgi与uWSGI