题目二 Element equals its index

434 阅读2分钟

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,那么这个时间肯定更加节省。