【题目标题】
在排序数组中查找元素第一个和最后一个位置
【题目描述】
给定一个按照升序排列的整数数组 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 <= 10⁵
-10⁹ <= nums[i] <= 10⁹
nums 是一个非递减数组
-10⁹ <= target <= 10⁹
【解题思路】
【二分查找法】
这道题涉及到在排序数组中查找指定元素,很明显是一个二分查找问题。只不过不同的是,需要找到相等元素的左右边界位置,所以需要在二分查找在中间位置与目标元素相等时,分别向中间位置两边查找。
【代码实现】
class Solution {
public int[] searchRange(int[] nums, int target) {
if (nums == null || nums.length == 0) {
return new int[]{-1, -1};
}
int left = compareMiddle(nums, target, true);
int right = compareMiddle(nums, target, false);
return new int[]{left, right};
}
private int compareMiddle(int[] nums, int target, boolean findLeftIndex) {
int left = 0;
int right = nums.length - 1;
int resultIndex = -1;
while (left < right) {
int middle = left + (right - left) / 2;
if (target < nums[middle]) {
right = (middle - 1) >= 0 ? middle - 1 : 0;
} else if (target > nums[middle]) {
left = (middle + 1) < nums.length ? middle + 1 : nums.length;
} else {
resultIndex = middle;
if (Boolean.TRUE.equals(findLeftIndex)) {
right = middle - 1;
} else {
left = middle + 1;
}
}
}
if (Boolean.TRUE.equals(findLeftIndex)) {
return (nums[left] == target) ? left : resultIndex;
} else {
return (nums[right] == target) ? right : resultIndex;
}
}
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END