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] Search for a Range 搜索一个范围的更多相关文章

  1. [LeetCode] 34. Search for a Range 搜索一个范围(Find First and Last Position of Element in Sorted Array)

    原题目:Search for a Range, 现在题目改为: 34. Find First and Last Position of Element in Sorted Array Given an ...

  2. [LeetCode] Search a 2D Matrix 搜索一个二维矩阵

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...

  3. [CareerCup] 11.6 Search a 2D Matrix 搜索一个二维矩阵

    11.6 Given an M x N matrix in which each row and each column is sorted in ascending order, write a m ...

  4. [LeetCode] 74. Search a 2D Matrix 搜索一个二维矩阵

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...

  5. LeetCode: Search for a Range 解题报告

    Search for a RangeGiven a sorted array of integers, find the starting and ending position of a given ...

  6. lintcode: search for a range 搜索区间

    题目 搜索区间 给定一个包含 n 个整数的排序数组,找出给定目标值 target 的起始和结束位置. 如果目标值不在数组中,则返回[-1, -1] 样例 给出[5, 7, 7, 8, 8, 10]和目 ...

  7. [LeetCode] Search for a Range [34]

    题目 Given a sorted array of integers, find the starting and ending position of a given target value. ...

  8. LeetCode Search for a Range (二分查找)

    题意 Given a sorted array of integers, find the starting and ending position of a given target value. ...

  9. [Leetcode] search a 2d matrix 搜索二维矩阵

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...

随机推荐

  1. JavaScript 垃圾回收

    在公司经常会听到大牛们讨论时说道内存泄露神马的,每每都惊羡不已,最近精力主要用在了Web 开发上,读了一下<JavaScript高级程序设计>(书名很唬人,实际作者写的特别好,由浅入深)了 ...

  2. 数百个 HTML5 例子学习 HT 图形组件 – 拓扑图篇

    HT 是啥:Everything you need to create cutting-edge 2D and 3D visualization. 这口号是当年心目中的产品方向,接着就朝这个方向慢慢打 ...

  3. C# 一段绘图代码 在form_load事件不能显示图

    今天无意将一段绘图代码 写在form_load事件了,结果不能显示绘图.(代码:Graphics g = this.CreateGraphics();Pen pen = new Pen(Color.R ...

  4. 【原创】如何确定Kafka的分区数、key和consumer线程数

    在Kafak中国社区的qq群中,这个问题被提及的比例是相当高的,这也是Kafka用户最常碰到的问题之一.本文结合Kafka源码试图对该问题相关的因素进行探讨.希望对大家有所帮助.   怎么确定分区数? ...

  5. [.NET Core].NET Core R2安装教程及Hello示例

    前言 前几天.NET Core发布了.NET Core 1.0.1 R2 预览版,之前想着有时间尝试下.NET Core.由于各种原因,就没有初试.刚好,前几天看到.NET Core发布新版本了,决定 ...

  6. Java - 网络编程

    Java的网络编程学习,关于计算机基础的学习参考:计算机网络基础学习 - sqh.     参考:  

  7. jdk安装

    x86 和 x64的安装判别 [root@CentOS ~]# uname -aLinux CentOS 2.6.32-358.el6.i686 #1 SMP Thu Feb 21 21:50:49 ...

  8. HTML5笔记1——HTML5的发展史及标签的改变

    记得第一次接触HTML5还是在<联信永益>实习那会儿(2011),当时一个项目技术选型的时候面临两种选择,分别是Silverlight和HTML5,那是用的最新的IE浏览器版本还是IE9, ...

  9. Java实现约瑟夫环

    什么是约瑟夫环呢? 约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个 ...

  10. css揭秘--笔记(未完)

    第0章 关于本书 1, 本书要用到一个工具函数————$$(),它可以让我们更容易获取和遍历所有匹配特定css选择符的dom元素: function $$(selector,context){ con ...