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

Your algorithm's runtime complexity must be in the order of O(log n).

If the target is not found in the array, return [-1, -1].

Example 1:

Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]

Example 2:

Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]

这道题让我们在一个有序整数数组中寻找相同目标值的起始和结束位置,而且限定了时间复杂度为 O(logn),这是典型的二分查找法的时间复杂度,所以这里也需要用此方法,思路是首先对原数组使用二分查找法,找出其中一个目标值的位置,然后向两边搜索找出起始和结束的位置,代码如下:

解法一:

class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int idx = search(nums, , nums.size() - , target);
if (idx == -) return {-, -};
int left = idx, right = idx;
while (left > && nums[left - ] == nums[idx]) --left;
while (right < nums.size() - && nums[right + ] == nums[idx]) ++right;
return {left, right};
}
int search(vector<int>& nums, int left, int right, int target) {
if (left > right) return -;
int mid = left + (right - left) / ;
if (nums[mid] == target) return mid;
if (nums[mid] < target) return search(nums, mid + , right, target);
else return search(nums, left, mid - , target);
}
};

可能有些人会觉得上面的算法不是严格意义上的 O(logn) 的算法,因为在最坏的情况下会变成 O(n),比如当数组里的数全是目标值的话,从中间向两边找边界就会一直遍历完整个数组,那么下面来看一种真正意义上的 O(logn) 的算法,使用两次二分查找法,第一次找到左边界,第二次调用找到右边界即可,具体代码如下:

解法二:

class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int> res(, -);
int left = , right = nums.size();
while (left < right) {
int mid = left + (right - left) / ;
if (nums[mid] < target) left = mid + ;
else right = mid;
}
if (right == nums.size() || nums[right] != target) return res;
res[] = right;
right = nums.size();
while (left < right) {
int mid = left + (right - left) / ;
if (nums[mid] <= target) left = mid + ;
else right = mid;
}
res[] = right - ;
return res;
}
};

其实我们也可以只使用一个二分查找的子函数,来同时查找出第一个和最后一个位置。如何只用查找第一个大于等于目标值的二分函数来查找整个范围呢,这里用到了一个小 trick,首先来查找起始位置的 target,就是在数组中查找第一个大于等于 target 的位置,当返回的位置越界,或者该位置上的值不等于 target 时,表示数组中没有 target,直接返回 {-1, -1} 即可。若查找到了 target 值,则再查找第一个大于等于 target+1 的位置,然后把返回的位置减1,就是 target 的最后一个位置,即便是返回的值越界了,减1后也不会越界,这样就实现了使用一个二分查找函数来解题啦,参见代码如下:

解法三:

class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int start = firstGreaterEqual(nums, target);
if (start == nums.size() || nums[start] != target) return {-, -};
return {start, firstGreaterEqual(nums, target + ) - };
}
int firstGreaterEqual(vector<int>& nums, int target) {
int left = , right = nums.size();
while (left < right) {
int mid = left + (right - left) / ;
if (nums[mid] < target) left = mid + ;
else right = mid;
}
return right;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/34

类似题目:

First Bad Version

参考资料:

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

https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/discuss/14699/Clean-iterative-solution-with-two-binary-searches-(with-explanation)

https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/discuss/14701/A-very-simple-Java-solution-with-only-one-binary-search-algorithm

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] 34. Find First and Last Position of Element in Sorted Array 在有序数组中查找元素的第一个和最后一个位置的更多相关文章

  1. Leetcode34.Find First and Last Position of Element in Sorted Array在排序数组中查找元素的位置

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

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

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

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

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

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

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

  5. 【LeetCode每天一题】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 ...

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

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

  7. [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 ...

  8. 【LeetCode】在排序数组中查找元素的第一个和最后一个位置【三次二分】

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

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

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

随机推荐

  1. vs2017离线包下载安装并且不占用C盘空间使用教程

    安装vs2017,前提是你的环境是.NET4.6,VS2017在下载好安装程序安装的时候,会根据你选择的功能模块来下载所需要的安装程序,微软.安卓和苹果等平台的SDK.模拟器和第三方扩展功能等会在用户 ...

  2. Kafka学习笔记之Kafka性能测试方法及Benchmark报告

    0x00 概述 本文主要介绍了如何利用Kafka自带的性能测试脚本及Kafka Manager测试Kafka的性能,以及如何使用Kafka Manager监控Kafka的工作状态,最后给出了Kafka ...

  3. ASP.NET MVC 中的过滤器

    这里用实例说明各种过滤器的用法,有不对的地方还请大神指出,共同探讨. 1. ActionFilter 方法过滤器: 接口名为 IActionFilter ,在控制器方法调用前/后执行. 在新建的MVC ...

  4. PhantomJS简单使用

    PhantomJS下载地址:   http://phantomjs.org/download.html 简单使用: from selenium import webdriver # 要想调用键盘按键操 ...

  5. Linux用户和权限——管理用户和用户组的命令

    Linux用户和权限——管理用户和用户组的命令 摘要:本文主要学习了在Linux系统中管理用户和用户组的命令. useradd命令 useradd命令可以用来创建新用户. 基本语法 useradd [ ...

  6. Java并发包——线程安全的Map相关类

    Java并发包——线程安全的Map相关类 摘要:本文主要学习了Java并发包下线程安全的Map相关的类. 部分内容来自以下博客: https://blog.csdn.net/bill_xiang_/a ...

  7. Python进阶(二)

    1.模块和包的概念 python的解决方案是把同名的模块放到不同的包中 1.1,导入模块 要使用一个模块,我们必须首先导入该模块.Python使用import语句导入一个模块.例如,导入系统自带的模块 ...

  8. Delphi Webbrowser使用方法详解

    1.webbroser介绍 该组件是一个浏览器组件,可以显示一个指定地址的网页.设置网页打开时的主页以及对网页进行相关的操作,同时也可以对HTML文件进行剪切.复制.粘贴.删除等操作.该 组件在Int ...

  9. 详解Vue的slot新用法

    摘要: 理解Vue插槽. 作者:前端小智 原文:vue 2.6 中 slot 的新用法 Fundebug经授权转载,版权归原作者所有. 为了保证的可读性,本文采用意译而非直译. 最近发布不久的Vue ...

  10. GCN 简单numpy实现

    `#参考:https://blog.csdn.net/weixin_42052081/article/details/89108966 import numpy as np import networ ...