题目链接
英文链接:https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/
中文链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/
题目详述
给定一个按照升序排列的整数数组 nums
,和一个目标值 target
。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是 O(log n) 级别。
如果数组中不存在目标值,返回 [-1, -1]
。
示例 1:
1 | 输入: nums = [5,7,7,8,8,10], target = 8 |
示例 2:
1 | 输入: nums = [5,7,7,8,8,10], target = 6 |
题目详解
- ”数组 + 有序“可以联想到二分查找。
- 找到数组中第一个大于或等于 target 的元素的下标,再找到数组中第一个大于 target 的元素的下标,就可以很容易得到目标值在数组中的开始位置和结束位置。
- 在 C++ STL 中,找到数组中第一个大于或等于 target 的元素的下标可以用函数 lower_bound(),找到数组中第一个大于 target 的元素的下标可以用函数 upper_bound()。在 Java 中没有类似的 API,我们可以自己实现 lower_bound() 和 upper_bound()。
- 实际上,LeetCode35-搜索插入位置 就是实现 lower_bound(),只不过 LeetCode35-搜索插入位置 假设数组中无重复元素,是 lower_bound() 的简化版。
1 | public class LeetCode_00034 { |
我们也可以直接搜索目标值的开始位置和结束位置。
- 假设目标值在闭区间
[l, r]
中, 每次将区间长度缩小一半,当l == r
时,我们就找到了目标值。 - 当我们将区间
[l, r]
划分成[l, mid]
和[mid + 1, r]
时,其更新操作是r = mid
或者l = mid + 1
,计算mid
时不需要加1
。first
不需要加1
。 - 当我们将区间
[l, r]
划分成[l, mid - 1]
和[mid, r]
时,其更新操作是r = mid - 1
或者l = mid
,此时为了防止死循环,计算mid
时需要加1
。last
不需要加1
。
1 | public class LeetCode_00034 { |