排序数组中查找元素的第一个和最后一个位置
1. 前言
在排序数组中查找元素的第一个位置和最后一个位置是一道常见的面试题和算法题,我们可以通过二分查找等算法来解决这个问题。在具体实现中,我们需要考虑多种情况,如数组为空、数组中只有一个元素,以及查找元素不存在等情况,还需要注意边界条件的处理。本篇文章将介绍在排序数组中查找元素的第一个和最后一个位置的相关算法及其实现。
2. 问题描述
给定一个按照升序排列的整数数组 nums
,和一个目标值 target
,找出在数组中的目标值的第一个位置和最后一个位置。如果目标值不在数组中,则返回 [-1, -1]
。
例如,给定数组 nums = [5, 7, 7, 8, 8, 10]
和目标值 target = 8
,应该返回 [3, 4]
。
3. 算法分析
3.1 二分查找法
二分查找法是一种高效的算法,适用于有序数组的查找操作。在本题中,我们需要找到目标元素的第一次和最后一次出现位置,因此我们可以分别使用两次二分查找法来完成这个问题。
在查找目标元素第一次出现位置时,我们可以先使用二分查找法找到目标元素的位置,再向左遍历,直到左边的元素不等于目标元素。同理,在查找目标元素最后一次出现位置时,我们可以使用二分查找法找到目标元素的位置,再向右遍历,直到右边的元素不等于目标元素。
具体实现可以参见下面的代码(Java 版本):
public int[] searchRange(int[] nums, int target) {
int[] res = {-1, -1};
if (nums == null || nums.length == 0) return res;
// 查找第一次出现的位置
int left = 0, right = nums.length - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) left = mid + 1;
else right = mid;
}
if (nums[left] != target) return res;
res[0] = left;
// 查找最后一次出现的位置
right = nums.length - 1;
while (left < right) {
int mid = left + (right - left) / 2 + 1;
if (nums[mid] > target) right = mid - 1;
else left = mid;
}
res[1] = left;
return res;
}
3.2 二分查找法改进
上面的代码实现并不是最优解,因为我们查找目标元素第一次和最后一次出现位置时都需要使用二分查找法,有一定的重复计算。为优化代码,我们可以设计一种更加高效的算法,只使用一次二分查找法即可完成任务。
具体思路是,首先使用二分查找法找到目标元素的位置,然后向该位置的左右两侧分别查找目标元素的第一次和最后一次出现位置。具体实现参见下面的代码(Java 版本):
public int[] searchRange(int[] nums, int target) {
int[] res = {-1, -1};
if (nums == null || nums.length == 0) return res;
int left = 0, right = nums.length - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) left = mid + 1;
else right = mid;
}
if (nums[left] != target) return res;
// 查找最后一次出现的位置
int l = left, r = nums.length - 1;
while (l < r) {
int mid = l + (r - l) / 2 + 1;
if (nums[mid] > target) r = mid - 1;
else l = mid;
}
res[1] = l;
// 查找第一次出现的位置
l = 0; r = left;
while (l < r) {
int mid = l + (r - l) / 2;
if (nums[mid] < target) l = mid + 1;
else r = mid;
}
res[0] = l;
return res;
4. 总结
在排序数组中查找元素的第一个位置和最后一个位置是一道常见的面试题和算法题,我们可以使用二分查找法等算法来解决这个问题。
具体实现中,需要仔细考虑多种情况,如数组为空、数组中只有一个元素,以及查找元素不存在等情况。另外,需要注意边界条件的处理,避免出现越界或死循环等问题。
在使用二分查找法时,我们可以通过一些技巧来优化算法效率,如使用单次查找法来查找目标元素的第一次和最后一次出现位置等。