34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)
给你一个按照非递减顺序排列的整数数组
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
class Solution {public int[] searchRange(int[] nums, int target) {int left = 0;int len = nums.length;int right = len-1;int mid = 0;int[] arr = new int[2];arr[0]=arr[1]=-1;if(len == 0) return arr;while(left < right) {mid = (left + right) / 2;if(nums[mid] < target) {left = mid;} else if(nums[mid] == target) {right = mid;} else {right = mid;}if(right - left == 1) break;}if(nums[left] == target) arr[0] = arr[1] = left;else if(nums[right] == target) arr[0] = arr[1] = right;left = 0;right = len-1;while(left < right) {mid = (left + right) / 2;if(nums[mid] < target) {left = mid;} else if(nums[mid] == target) {left = mid;} else {right = mid;}if(right - left == 1) break;}if(nums[right] == target) {arr[1] = right;if(arr[0] == -1) arr[0] = right;}else if(nums[left] == target) {arr[1] = left;if(arr[0] == -1) arr[0] = left;}return arr;}
}
每日一题,今天是中等题。今天仍然是和二分相关的题目,还是边界的判断问题。
看完题目,要求我们使用O(log(n))的算法。O(log(n))算法,递增数组,查找下标,就是二分查找算法了。但是,之前也说过,题目明显的二分查找算法,肯定会对各种边界有所要求。这道题目要求我们找出目标在数组中最开始和最后面的下标。可以使用二分,但一次二分显然是不够的。如果一整个数组全都是目标数呢?很显然二分一次只能往左找最靠近左边的,第二次往右找最靠近右边的。之后对找到的下标进行边界的判断。如果最左边找到的和目标数相等,那么要么就是只有那个数,要么就是右边还有一个。第二次找右边的也一样,如果第一次的时候左边没找到,说明可能只有右边一个数,或者右边的左边一个数也是。
纯二分就做好边界判断,多练习。