给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

你的算法时间复杂度必须是 O(log n) 级别。

如果数组中不存在目标值,返回 [-1, -1]。

示例 1:

输入: nums = [5,7,7,8,8,10], target = 8

输出: [3,4]

示例 2:

输入: nums = [5,7,7,8,8,10], target = 6

输出: [-1,-1]

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array

分析:

数组有序,要求时间复杂度是O(log N),可以联想到二分

先直接在整个数组中二分找target,假设没有找到,那么返回[-1,-1]即可

假设找到了target,位置索引是k,那么在区间[0,k-1],[k+1,n-1]都进行二分寻找target

两个区间寻找target只有四种结果:

假设两个区间找到了target的索引为k1和k3,第一次找到的target索引为k2

1)第一个区间找到,第二个区间没有找到,返回结果:[k1,k2]

2)第一个区间找到,第二个区间找到,返回结果:[k1,k3]

3)第一个区间没有找到,第二个区间找到,返回结果:[k2,k3]

4)第一个区间没有找到,第二个区间没有找到,返回结果:[k2,k2]

总结:先进行一次二分寻找目标值是否存在,然后分别在目标值的两边进行两次二分寻找左右端点

总共三次二分

时间复杂度:O(log N)

空间复杂度:O(1)

class Solution {
public: //二分函数
int f(vector<int>& v,int l,int h,int t,int flag)
{
int k1=INT_MAX;
int k3=INT_MIN;
while(l<=h)
{
int mid=(l+h)/2;
if(v[mid]==t)
{
if(flag==1)
k1=min(k1,mid);
else if(flag==3)
k3=max(k3,mid);
else if(flag==2)
return mid;
if(v[l]==t)
{
k1=min(k1,l);
k3=max(k3,l);
}
if(v[h]==t)
{
k1=min(k1,h);
k3=max(k3,h);
}
l++;//找到了也要继续找下去
h--;
}
else if(v[mid]>t)
{
h=mid-1;
}
else if(v[mid]<t)
{
l=mid+1;
}
}
if(flag==1&&k1!=INT_MAX)
return k1;
if(flag==3&&k3!=INT_MIN)
return k3;
return -1;
}
vector<int> searchRange(vector<int>& v, int t)
{
vector<int> ans;
int n=v.size();
int k2=f(v,0,n-1,t,2);//第一次二分判断target是否存在
if(k2==-1)
{
ans.push_back(-1);
ans.push_back(-1);
return ans;
}
//在target的两端各自进行一次二分确定左右区间端点值
int k1=f(v,0,k2-1,t,1);
int k3=f(v,k2+1,n-1,t,3); //根据二分结果确定结果区间
if(k1==-1)
ans.push_back(k2);
else
ans.push_back(k1);
if(k3==-1)
ans.push_back(k2);
else
ans.push_back(k3);
return ans;
}
};

【LeetCode】在排序数组中查找元素的第一个和最后一个位置【三次二分】的更多相关文章

  1. Java实现 LeetCode 34 在排序数组中查找元素的第一个和最后一个位置

    在排序数组中查找元素的第一个和最后一个位置 给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置. 你的算法时间复杂度必须是 O(log n ...

  2. 【LeetCode】34. 在排序数组中查找元素的第一个和最后一个位置

    34. 在排序数组中查找元素的第一个和最后一个位置 知识点:数组,二分查找: 题目描述 给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置 ...

  3. 34、在排序数组中查找元素的第一个和最后一个位置 | 算法(leetode,附思维导图 + 全部解法)300题

    零 标题:算法(leetode,附思维导图 + 全部解法)300题之(34)在排序数组中查找元素的第一个和最后一个位置 一 题目描述 二 解法总览(思维导图) 三 全部解法 1 方案1 1)代码: / ...

  4. Leetcode题目34.在排序数组中查找元素的第一个和最后一个位置(中等)

    题目描述: 给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置. 你的算法时间复杂度必须是 O(log n) 级别. 如果数组中不存在目标 ...

  5. 【LeetCode】34-在排序数组中查找元素的第一个和最后一个位置

    题目描述 给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置. 你的算法时间复杂度必须是 O(log n) 级别. 如果数组中不存在目标值 ...

  6. LeetCode 34 - 在排序数组中查找元素的第一个和最后一个位置 - [二分][lower_bound和upper_bound]

    给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置. 你的算法时间复杂度必须是 O(log n) 级别. 如果数组中不存在目标值,返回 [ ...

  7. #leetcode刷题之路34-在排序数组中查找元素的第一个和最后一个位置

    给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置.你的算法时间复杂度必须是 O(log n) 级别.如果数组中不存在目标值,返回 [-1 ...

  8. C#LeetCode刷题之#34-在排序数组中查找元素的第一个和最后一个位置(Find First and Last Position of Element in Sorted Array)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4970 访问. 给定一个按照升序排列的整数数组 nums,和一个目 ...

  9. [Swift]LeetCode34. 在排序数组中查找元素的第一个和最后一个位置 | Find First and Last Position of Element in Sorted Array

    Given an array of integers nums sorted in ascending order, find the starting and ending position of ...

随机推荐

  1. JS树结构转list结构

    树转list /** * 树转list */ function treeToList(tree){ for(var i in tree){ var node = tree[i]; list = []; ...

  2. Java代码中可以优化性能的小细节

    避免对boolean类型的判定 反例: 12 if("a".equles("a")==true)`{} 正例: 12 if(Objects.equles(&qu ...

  3. Spring Cloud Gateway转发Spring WebSocket

    Spring Cloud Gateway转发Spring WebSocket 源码:https://github.com/naah69/SpringCloud-Gateway-WebSocket-De ...

  4. 【夯实基础】-浅谈"单点登录"的几种实现方式

    单点登录 一.Session跨域 所谓Session跨域就是摒弃了系统提供的Session,而使用自定义的类似Session的机制来保存客户端数据的一种解决方案. 如:通过设置cookie的domai ...

  5. vue 的 Class 与 Style 绑定

    操作元素的 class 列表和内联样式是数据绑定的一个常见需求.因为它们都是属性,所以我们可以用 v-bind 处理它们:只需要通过表达式计算出字符串结果即可.不过,字符串拼接麻烦且易错.因此,在将 ...

  6. SQLMAP源码阅读(一)

  7. 【软件工程第三次作业】结对编程:四则运算( Java 实现)

    1. GitHub 地址 本项目由 莫少政(3117004667).余泽端(3117004679)结对完成. 项目 GitHub 地址:https://github.com/Yuzeduan/Arit ...

  8. Odoo form视图详解

    转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826350.html 一:Header头部 header区域一般用于展示文档流转的阶段和生命周期,以及动作 ...

  9. XGBoost使用教程(与sklearn一起使用)二

    一.导入必要的工具包# 运行 xgboost安装包中的示例程序from xgboost import XGBClassifier # 加载LibSVM格式数据模块from sklearn.datase ...

  10. css 高度随宽度比例变化

    [方案一:padding实现] 原理: 一个元素的 padding,如果值是一个百分比,那这个百分比是相对于其父元素的宽度而言的,padding-bottom 也是如此. 使用 padding-bot ...