Element equals its index
Given a sorted array of distinct integers, write a function indexEqualsValue that returns the lowest index for which array[index] == index. Return -1 if there is no such index.
Your algorithm should be very performant.
[input] array of integers ( with 0-based nonnegative indexing ) [output] integer
Examples: input: [-8,0,2,5] output: 2 # since array[2] == 2
input: [-1,0,3,6] output: -1 # since no index in array satisfies array[index] == index Random Tests Constraints: Array length: 200 000
Amount of tests: 1 000
Time limit: 150 ms
这个题目很容易就想到运用for循环 找到第一个坐标和位置相同的元素就返回。 代码也很简单
function indexEqualsValue(a) {
for(let i = 0; i < a.length; i++){
if(a[i] == i) return i;
}
}
但是题目的要求是在150毫秒返回,如果在数据特别多的情况,一个个遍历过去那一定是要超时的。
这里就用到了二分法,采用二分法查找时,必须是排序好的数组。 其主要思想是查找数组范围[min,max],如果和其中间值相等 那么返回查找值,反之重新确定查找范围。
这一题就可以用这个思路,先比较a[mid] 比中间值大还是小,小的话就把max设为mid,反之亦然。 但是这道题目需要找到数组中的第一个值,要是有多个解,就会返回靠近中间的值。需要对这个算法逻辑,做一些小小的改动。
function indexEqualsValue(a) {
let low = 0, high = a.length;
let result = -1;
while(low < high){
let mid = Math.floor((low + high)/2);
if(a[mid] < mid) {
low = mid + 1;
}
else if(a[mid] > mid) {
high = mid;
}
else {
high = mid;
result = mid;
}
}
return result;
}
else {
high = mid;
result = mid;
}
关键就是这一点,保存范围最大值,并且保存返回结果。
这个二分法的时间复杂度是log2n,遍历的时间复杂度是n,那么这个时间肯定更加节省。