JS二分法与二维数组的查找

假如我们现在有个二维数组,数据量比较大,规律是: 每一行都是增加的,每一列也是增加的,即后面的数比前面的大。如下面的数组a。 如何查找某个元素在里面的坐标以及个数呢?
因为考虑二维数组的数据量很大,我们不可能全部遍历,所以采用二分法。
(右上角的数字就是该行最大,所在列最小的数字。如果这个数比要找的数还大,那么它之后的列就不需要再找,以这个规律以及二分法定位需要查找的最大列数来提高查询)。直接上例子

var a = [
  [1,2,8,9],
  [2,4,9,12],
  [4,7,10,13],
  [6,8,11,15]
]

// 查询最大列数
function halfFind(arr, num) {
  var max_index =  arr[0].length -1
  var min_index =  0
  var ret;
  if (arr[0][max_index] <= num) {
      return max_index
  }
  do {
    var half_index = Math.ceil((max_index + min_index)/2)
    var value = arr[0][half_index]
    if( value > num){
       max_index = half_index
    } else {
       min_index = half_index
    }
    ret = min_index
  } while (max_index - min_index >1)
  return ret
}

// 垂直查找最大行数
function halfFind_column(arr, num, column, init_min_index) {
   var max_index = arr.length -1
   var min_index = init_min_index || 0
   var ret
   if (arr[max_index][column] == num) {
      return max_index
   }
   do {
     var half_index = Math.ceil((max_index + min_index)/2)
     var value = arr[half_index][column]
     if(value > num) {
       max_index = half_index
     } else {
       min_index = half_index
     }
     ret = min_index
   } while (max_index - min_index >1)
   return ret
}
   
function getIndex(arr, num) {
  // 边界判定
  if(arr[0][0] > num || arr[arr.length - 1][arr[0].length - 1] < num ) {
     return -1
  }
 
  // 需要计算的最大列[0,column]列数区间
  var column = halfFind(arr, num)
  var result_arr = []
  var v_index = 0
  for (var i= column;i>-1;i--) {
    v_index = halfFind_column(arr, num, i, v_index)
    if (arr[v_index][i] == num) {
      result_arr.push([v_index, i])
    }
  }
  return result_arr
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。