要求
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
每行中的整数从左到右按升序排列。
每行的第一个整数大于前一行的最后一个整数。
示例 1:
输入:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 3
输出: true
示例 2:
输入:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 13
输出: false
方法一:二分查找
设起始元素为 a, 末尾元素为 b 找出中间元素 c.
二维数组求中间元素所在位置: 假设二维数组有m*n个元素, 中间元素索引为x, x / n 为 rowIndex, x % n 则为 columnIndex。x = row * m … column.
若target > c,则target位于(c,b).此时low = middleIndex + 1;
若target < c,则target位于(a,c).此时high = middleIndex - 1;
var searchMatrix = function(matrix, target) {
if(matrix.length === 0)
return false;
let row = matrix.length;
let column = matrix[0].length;
let low = 0;
let high = row * column;
while(low <= high) {
let middleIndex = low + Math.floor((high - low) / 2);
let middleRowIndex = Math.floor(middleIndex / column);
let middleColumnIndex = Math.floor(middleIndex % column);
if(matrix[middleRowIndex][middleColumnIndex] < target)
low = middleIndex + 1;
else if(matrix[middleRowIndex][middleColumnIndex] > target)
high = middleIndex - 1;
else
return true;
}
return false;
}
方法二
右上角或左下角开始搜索
因為这两个角开始搜索大于或小于时才不会有其中之一跳出矩阵
假設從右下角開始, 假设值大于矩阵所有数,此时row++则超出数组长度,同理左上角.
搜索移动轨迹:target 比所在坐标值大则移向下一行,比所在坐标值小则向前移动一列.然后不断进行移动.
var searchMatrix = function(matrix, target) {
if(matrix.length === 0) {
return false;
}
let row = 0;
let column = matrix[0].length - 1;
while(row <= matrix.length - 1 && column >= 0) {
if(target > matrix[row][column])
row++;
else if(target < matrix[row][column])
column--;
else
return true;
}
return false;
};