文章目录
- 前言
- 二分查找简介
- 一、二分查找
- 1.1 题目描述
- 1.2 题目解析
- 1.2.1 算法原理
- 1.2.2 代码编写
- 二、在排序数组中查找元素的第一个和最后一个位置
- 2.1 题目描述
- 2.2 题目解析
- 2.2.1 算法原理
- 2.2.2 代码编写
- 总结
前言
二分查找简介
定义:
二分就是每次把当前需要寻找的数组分成两半,那么我需要寻找的这个数只可能在左半边,或者右半边,这样一来我每次分完,所需要查找的元素的个数就是上一次查找元素个数的一半。
思路:
先找出当前判断的数组中点,将目标值与当前中点值比较,判断是继续在左侧查找还是在右侧查找,直到需要判断的数组元素为1个时,判断此元素是否是需要查的元素,若是则返回该元素下标,否则则返回-1,结束查找。
特点:
细节最多,最容易写出死循环的算法;
注意:二分查找不止适用于数组有序,数组无序的一些问题依然可以用二分查找,只要找出其中的规律,再在模板上进行适当修改即可;
二分查找模板有3种:
(1)朴素的二分模板;(2)查找左边界的二分模板;
(3)查找右边界的二分模板;
一、二分查找
1.1 题目描述
描述:
给定一个
n
个元素有序的(升序)整型数组nums
和一个目标值target
,写一个函数搜索nums
中的target
,如果目标值存在返回下标,否则返回-1
。
提示:
- 你可以假设
nums
中的所有元素是不重复的。n
将在[1, 10000]
之间。nums
的每个元素都将在[-9999, 9999]
之间。
示例1:
实例2:
1.2 题目解析
1.2.1 算法原理
本题我们采用二分查找的方法进行解决;
解题步骤:
步骤一: 首先定义 left , right 指针,分别指向数组的左右区间。
步骤二:找到待查找区间的中间点 mid ,找到之后分三种情况讨论:
情况1: arr[mid] == target 说明正好找到,返回 mid 的值;
情况2:arr[mid] > target 说明 [mid, right] 这段区间都是⼤于 target 的,因此舍
去右边区间,在左边 [left, mid -1] 的区间继续查找,即让 right = mid - 1 ,然后重复 2 过程;
情况3:arr[mid] < target 说明 [left, mid] 这段区间的值都是⼩于 target 的,因此舍去左边区间,在右边 [mid + 1, right] 区间继续查找,即让 left = mid + 1 ,然后重复 2 过程;
步骤三:
当 left 与 right 错开时,说明整个区间都没有这个数,返回 -1 。
1.2.2 代码编写
代码解析:
二、在排序数组中查找元素的第一个和最后一个位置
2.1 题目描述
描述:
给你一个按照非递减顺序排列的整数数组
nums
,和一个目标值target
。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值
target
,返回[-1, -1]
。你必须设计并实现时间复杂度为
O(log n)
的算法解决此问题。
提示:
0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums
是一个非递减数组-109 <= target <= 109
示例1:
示例2:
示例3: