编写一个高效的算法来判断 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
示例 3:
输入: matrix = [[]] ,target = 0
输出: false
解法一:
常用方法。将矩阵从末尾到首位遍历一遍,找到目标值或者遍历结束即返回。
// 2018/11/18 Sun 晚上
var searchMatrix = function(matrix, target) {
if(matrix.length<1 || matrix.length[0]<1) return false;
var num1=matrix.length-1,num2=matrix[0].length-1;
while(num1>=0){
if(matrix[num1][num2]==target){
return true;
}
if(num2<0){
num1-=1;
num2=matrix[0].length-1
continue;
}
num2--;
}
return false;
};
136 / 136 个通过测试用例
执行用时:88 ms
解法二:
遍历每个二维矩阵末尾的值是否大于目标值,是的话返回当前的索引。
再从返回的索引数组找与目标值相等的数字。
// 2018/11/18 Sun 晚上
var searchMatrix = function(matrix, target) {
if(matrix.length<1 || matrix.length[0]<1) return false;
var len1=matrix.length-1,len2=matrix[0].length-1, i=0,j=0,tar=-1;
while(i<=len1){
if(matrix[i][len2]>=target){
tar=i; break;
}
i++;
}
while(tar>-1 && j<=len2){
if(matrix[tar][j]==target) return true;
j++;
}
return false;
};
136 / 136 个通过测试用例
执行用时:72 ms
解法三:
使用二分查找法,
首先找到目标值在第一维的位置,其次找到目标值在第二维的准确位置,当两次都成功找到就返回true。
果然二分是三个中最快的~
// 2018/11/19 Mon 晚上
var searchMatrix = function(matrix, target) {
if(matrix.length<1 || matrix.length[0]<1) return false;
var len1=matrix.length-1,len2=matrix[0].length-1;
var lo=0,hi=len1,low=0,hei=len2, mid,middle
while(lo<=hi){
mid=Math.ceil((lo+hi)/2)
if(matrix[mid][0]<=target && matrix[mid][len2]>=target){
break;
}else if(matrix[mid][0]<=target){
lo=mid+1
}else{
hi=mid-1
}
}
while(low<=hei){
middle=Math.ceil((low+hei)/2)
if(matrix[mid][middle]==target){
return true
}else if(matrix[mid][middle]<target){
low=middle+1
}else{
hei=middle-1
}
}
return false;
}
136 / 136 个通过测试用例
执行用时:68 ms