假如我们现在有个二维数组,数据量比较大,规律是: 每一行都是增加的,每一列也是增加的,即后面的数比前面的大。如下面的数组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
}