剑指offer51_数组中数值和下标相等的元素
数组中数值和下标相等的元素
假设一个单调递增的数组里的每个元素都是整数并且是唯一的。
请编程实现一个函数找出数组中任意一个数值等于其下标的元素。
例如,在数组 [ − 3 , − 1 , 1 , 3 , 5 ] [−3,−1,1,3,5] [−3,−1,1,3,5] 中,数字 3 和它的下标相等。
数据范围
数组长度 [ 1 , 100 ] [1,100] [1,100]。
样例
输入:[-3, -1, 1, 3, 5]输出:3
注意:如果不存在,则返回-1。
算法思路
- 初始化指针:左指针
l
初始化为 0,右指针r
初始化为数组长度。 - 二分查找:
- 计算中间位置
mid
。 - 检查
nums[mid]
是否大于或等于mid
:- 如果是,说明目标元素在左半部分或当前位置,调整右指针
r = mid
。 - 否则,目标元素在右半部分,调整左指针
l = mid + 1
。
- 如果是,说明目标元素在左半部分或当前位置,调整右指针
- 计算中间位置
- 验证结果:循环结束后检查
nums[l]
是否等于l
,如果是则返回l
,否则返回 -1。
- 时间复杂度:O(log n),其中 n 是数组的长度。因为算法使用了二分查找,每次都将搜索范围减半。
- 空间复杂度:O(1),只使用了常数级别的额外空间。
class Solution {
public:int getNumberSameAsIndex(vector<int>& nums) {int l = 0, r = nums.size();while(l < r){int mid = l + r >> 1;if(nums[mid] >= mid) r = mid;else l = mid + 1;}if(nums[l] == l) return l; else return -1;}
};
注意事项
- 边界条件:循环结束后需检查
nums[l]
是否等于l
,避免数组越界或无效结果。 - 输入处理:若数组为空,直接返回 -1。
- 二分查找细节:确保
mid
的计算和指针调整正确,避免死循环或遗漏解。