leetcode原题链接:HOT65-在排序数组中查找元素的第一个和最后一个位置
题目描述
给你一个按照非递减顺序排列的整数数组 nums
,和一个目标值 target
。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target
,返回 [-1, -1]
。
你必须设计并实现时间复杂度为 O(log n)
的算法解决此问题。
示例 1:
输入:nums = [5,7,7,8,8,10] , target = 8 输出:[3,4]
示例 2:
输入:nums = [5,7,7,8,8,10] , target = 6 输出:[-1,-1]
示例 3:
输入:nums = [], target = 0 输出:[-1,-1]
提示:
0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums
是一个非递减数组-109 <= target <= 109
解题方法:二分查找。
左边界: target <= nums[mid],则缩小查找范围, right = mid - 1;循环结束的时候: left = right + 1, left指向第一个大于target或者第一个target的位置;
右边界:target >= num[mid],则扩大查找范围, right=mid+1,循环结束的时候, left=right+1,left指向第一个大于target或最右侧target的位置。
最后,值得注意的是,还需判断下返回的left或者right与对应的边界位置进行大小比较。
C++代码
#include <iostream>
#include <vector>/*
* [2,2,3] ==> target=2, 解存在,left指向第一个target, right为-1
* [5, 7] ==> target=6, 解不存在, left指向7, right指向5
* [2] ==> target=3, 解不存在, 循环结束后left越界
* [5] ==> target=3, 解不存在, 循环结束后right越界
*/
class Solution {
public:std::vector<int> searchRange(std::vector<int>& nums, int target) {int lower_idx = get_lower_bound_index(nums, target);int upper_idx = get_upper_bound_index(nums, target);return {lower_idx, upper_idx};}int get_lower_bound_index(std::vector<int>& nums, int target) {int n = nums.size();int left = 0;int right = n - 1;while (left <= right) {int mid = (left + right) / 2;if (target <= nums[mid]) { //这个条件决定了最终循环结束后,right指向第一个目标元素的前一个位置right = mid - 1; //目标更小,则缩小查找范围} else {left = mid + 1;}}// 循环结束后,如果存在目标值,则left指针指向第一个targe值的位置, right指向left的左边if (left < n && nums[left] == target) {return left;}return -1;}int get_upper_bound_index(std::vector<int>& nums, int target) {int n = nums.size();int left = 0;int right = n - 1;while (left <= right) {int mid = (left + right) / 2;if (target >= nums[mid]) { // 这个条件决定了最终循环结束后,left指向最后一个目标元素的下一个位置left = mid + 1;//目标更大,则扩大查找范围} else {right = mid - 1;}}// 循环结束后,,如果存在目标值,则right指向最后一个目标值的位置,left指向riht的右边(第一个大于target值的位置)if (right >= 0 && nums[right] == target) {return right;}return -1;}
};