【算法专题突破】二分查找 - 在排序数组中查找元素的第一个和最后一个位置(17)

简介: 【算法专题突破】二分查找 - 在排序数组中查找元素的第一个和最后一个位置(17)

目录

1. 题目解析

2. 算法原理

3. 代码编写

写在最后:


1. 题目解析

题目链接:34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)

这道题就是找出目标值在数组中的起始位置和结束位置。

2. 算法原理

这里如果我们直接使用标准的二分去做,如果整个数组都是是同一个数,

就会退化成 O(N),所以这里我们需要对他进行一个优化,

1. 先从查找左端点开始分析:设 x 为 mid 值,t 为目标值

如果 x < t ,left = mid + 1

如果 x >= t ,right = mid(我们这里把大于和等于的情况合并了)

这样设置就在 left == right 的时候就是最终结果,

而我们求中点的方式必须是 left + ( right - left ) / 2(也就是求偶数的形式)

这样每步走会靠近左端点,就不会陷入死循环。

2. 我们再来分析查找右端点

如果 x <= t ,left = mid(为什么这里不用 + 1,因为如果刚好落在目标值上,不久越过了吗)

如果 x > t ,right = mid - 1

这样当 left == right 的时候也就是最终结果了,

而我们求中点的方式就得是 left + ( right - left + 1 ) / 2

这样每步走会靠近右端点,就不会陷入死循环。

3. 代码编写

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        if(nums.size() == 0) return {-1, -1}; // 处理越界
        int left = 0, right = nums.size() - 1, begin = 0;
        while(left < right) {
            int mid = left + (right - left) / 2;
            if(nums[mid] < target) left = mid + 1;
            else right = mid;
        }
        if(nums[left] != target) return {-1, -1};
        else begin = left;
        left = 0, right = nums.size() - 1;
        while(left < right) {
            int mid = left + (right - left + 1) / 2;
            if(nums[mid] <= target) left = mid;
            else right = mid - 1;
        }
        return {begin, right};
    }
};

4. 二分的模板

查找左端点的时候:

       while(left < right) {

           int mid = left + (right - left) / 2;

           if(...) left = mid + 1;

           else right = mid;

       }

while (left < right) {
  int mid = left + (right - left) / 2;
  if (...) left = mid + 1;
  else right = mid;
}

查找右端点的时候:

       while(left < right) {

           int mid = left + (right - left + 1) / 2;

           if(...) left = mid;

           else right = mid - 1;

       }

while (left < right) {
  int mid = left + (right - left + 1) / 2;
  if (...) left = mid;
  else right = mid - 1;
}

写在最后:

以上就是本篇文章的内容了,感谢你的阅读。

如果感到有所收获的话可以给博主点一个哦。

如果文章内容有遗漏或者错误的地方欢迎私信博主或者在评论区指出~

相关文章
|
3月前
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
64 3
|
10天前
|
算法 索引
【算法】——二分查找合集
二分查找基础模版和进阶模版,查找元素位置,搜索插入位置,x的平方根,山脉数组的峰顶索引,寻找峰值,点名
|
3月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
55 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
3月前
|
存储 算法 Java
Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性
Java Set因其“无重复”特性在集合框架中独树一帜。本文解析了Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性,并提供了最佳实践建议,包括选择合适的Set实现类和正确实现自定义对象的hashCode()与equals()方法。
56 4
|
3月前
|
算法 C# 索引
C#二分查找算法
C#二分查找算法
|
3月前
|
存储 算法 定位技术
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
这篇文章主要介绍了稀疏数组和队列的概念、应用实例以及如何使用数组模拟队列和环形队列的实现方法。
31 0
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
|
3月前
|
存储 算法 C语言
【C语言】二分查找算法
【C语言】二分查找算法
|
3月前
|
消息中间件 存储 算法
一文搞懂二分查找算法!
一文搞懂二分查找算法!
147 0
|
3月前
|
算法 Java 索引
数据结构与算法学习十五:常用查找算法介绍,线性排序、二分查找(折半查找)算法、差值查找算法、斐波那契(黄金分割法)查找算法
四种常用的查找算法:顺序查找、二分查找(折半查找)、插值查找和斐波那契查找,并提供了Java语言的实现代码和测试结果。
38 0
|
11天前
|
机器学习/深度学习 算法
基于改进遗传优化的BP神经网络金融序列预测算法matlab仿真
本项目基于改进遗传优化的BP神经网络进行金融序列预测,使用MATLAB2022A实现。通过对比BP神经网络、遗传优化BP神经网络及改进遗传优化BP神经网络,展示了三者的误差和预测曲线差异。核心程序结合遗传算法(GA)与BP神经网络,利用GA优化BP网络的初始权重和阈值,提高预测精度。GA通过选择、交叉、变异操作迭代优化,防止局部收敛,增强模型对金融市场复杂性和不确定性的适应能力。
145 80

热门文章

最新文章