(LeetCodeHot100)34. 在排序数组中查找元素的第一个和最后一个位置——find-first-and-last-position-of-element-in-sorted-array
(LeetCodeHot100)34. 在排序数组中查找元素的第一个和最后一个位置——find-first-and-last-position-of-element-in-sorted-array
zhangzhang34. 在排序数组中查找元素的第一个和最后一个位置——find-first-and-last-position-of-element-in-sorted-array
给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。
示例 1:
1 | 输入:nums = [5,7,7,8,8,10], target = 8 |
示例 2:
1 | 输入:nums = [5,7,7,8,8,10], target = 6 |
示例 3:
1 | 输入:nums = [], target = 0 |
提示:
0 <= nums.length <= 105-109 <= nums[i] <= 109nums是一个非递减数组-109 <= target <= 109
我的正确答案:
- 还是有点巧妙的,先找到一个target,再左右两边试探一下
1 | class Solution { |
官方解答:
方法:二分查找
直观的思路肯定是从前往后遍历一遍。用两个变量记录第一次和最后一次遇见 target 的下标,但这个方法的时间复杂度为 O(n),没有利用到数组升序排列的条件。
由于数组已经排序,因此整个数组是单调递增的,我们可以利用二分法来加速查找的过程。
考虑 target 开始和结束位置,其实我们要找的就是数组中「第一个等于 target 的位置」(记为 leftIdx*)和「第一个大于 *target 的位置减一」(记为 rightIdx)。
二分查找中,寻找 leftIdx 即为在数组中寻找第一个大于等于 target 的下标,寻找 rightIdx 即为在数组中寻找第一个大于 target 的下标,然后将下标减一。两者的判断条件不同,为了代码的复用,我们定义 binarySearch(nums, target, lower) 表示在 nums 数组中二分查找 target 的位置,如果 lower 为 true,则查找第一个大于等于 target 的下标,否则查找第一个大于 target 的下标。
最后,因为 target 可能不存在数组中,因此我们需要重新校验我们得到的两个下标 leftIdx 和 rightIdx,看是否符合条件,如果符合条件就返回 [leftIdx,rightIdx],不符合就返回 [−1,−1]。
1 | class Solution { |
复杂度分析
- 时间复杂度: O(logn) ,其中 n 为数组的长度。二分查找的时间复杂度为 O(logn),一共会执行两次,因此总时间复杂度为 O(logn)。
- 空间复杂度:O(1) 。只需要常数空间存放若干变量
原创(LeetCodeHot100)34. 在排序数组中查找元素的第一个和最后一个位置——find-first-and-last-position-of-element-in-sorted-array
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 zhangzhang-blog!


