LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置
https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/comments/
给你一个按照非递减顺序排列的整数数组 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]
Solution
二分 + 向左向右遍历(Java),时间复杂度: O ( l o g n + n ) O(log n + n) O(logn+n):
class Solution {
public int[] searchRange(int[] a, int target) {
int[] ans = {-1, -1};
int l = 0, r = a.length - 1, mid = 0;
// 先二分找到 target 对应的数
while (l <= r) {
mid = (l + r) / 2;
if (a[mid] == target) {
ans[0] = mid;
ans[1] = mid;
break;
} else if (a[mid] < target) {
l = mid + 1;
} else {
r = mid - 1;
}
}
// 向 target 左面和右面分别进行遍历找到等于 target 的最小索引和最大索引
for (int i = mid - 1; i >= 0; i--) {
if (a[i] != target) {
break;
}
ans[0] = i;
}
for (int i = mid + 1; i < a.length; i++) {
if (a[i] != target) {
break;
}
ans[1] = i;
}
return ans;
}
}
二分找最大最小下标(C) ,时间复杂度:
O
(
l
o
g
n
)
O(log n)
O(logn) :
searchInsert()
函数直接 Copy 之前写过的 LeetCode 35. 搜索插入位置的代码,该代码会找到等于 target
值的最小下标。
int searchInsert(int* a, int n, int target){
int l = 0, r = n - 1;
int ans = n;
int mid;
while (l <= r) {
mid = (l + r) / 2;
if (a[mid] >= target) {
ans = mid;
r = mid - 1;
} else {
l = mid + 1;
}
}
return ans;
}
int* searchRange(int* nums, int numsSize, int target, int* returnSize){
int *reslut = (int*) malloc(sizeof(int) * 2);
*returnSize = 2; // 这个必须加,不加报错
reslut[0] = reslut[1] = -1;
// 找插入 target 位置的最小索引
int left_idx = searchInsert(nums, numsSize, target);
// 若最小下标小于表长并且找到的最小索引对应的数 == target
if (left_idx < numsSize && nums[left_idx] == target) {
reslut[0] = left_idx;
// 寻找插入 (target + 1) 最小索引值 - 1
// (target + 1) 的最小索引值 - 1 表示等于 target 的最大索引值
reslut[1] = searchInsert(nums, numsSize, target + 1) - 1;
}
return reslut;
}