很漂亮的一道题,binary search的典型变体。个人觉得考察的点就是,binary search的最终结束状态的left 和right 在哪里!!再次体现了,right这个坐标的重要属性:即这个right最终的index位置是小于target的最大值!或者说left在target左边,right在target的右边。怕记混的话,就只要举一个例子,当left和right相邻时,比如在 index 4 & 5 的位置,所指的值分别是 10 & 20, target的话就3种情况,5, 15, 25。right的最终值是,越左界,4,5。这和上述结论就是一致的。更加形象的例子就是,left 和 right 都是辛勤的小蜜蜂,都想接近全力去找到target,只要有机会(能够往右跳也能够往左跳,就都会跳)就一定会跳,直到没有机会条了。也就是说,left只能往右移动,right只能往左移动,最终结束时,都是left跳到target右边,right跳到target左边!这样理解的话就可以很直接判断left和right的最终状态。
代码
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
if(matrix.length==0 || matrix[0].length==0) return false;
int low=0, high=matrix.length-1;
while(low<=high){
int mid= low+(high-low)/2;
if(target==matrix[mid][0]) return true;
else if(target>matrix[mid][0]) low=mid+1;
else high=mid-1;
}
if(high==-1) return false;
int left=0, right=matrix[0].length-1;
while(left<=right){
int mid= left+(right-left)/2;
if(target==matrix[high][mid]) return true;
else if(target>matrix[high][mid]) left=mid+1;
else right =mid-1;
}
return false;
}
}
思路总结:
1,第一列的binary search,确定行的index,那么col index 就一直是0
2,在目标行进行binary search,那么row index 就一直是 high
之后又思考了复杂度,时间复杂度是 logN + log M, 不是 logN*LogM哦,因为确定了一行后,只要对该行进行binary search
那么如果把这个matrix stretch 成一个sorted array,用binary search,时间复杂度是 log(N*M),其实也是一样的。
嗯,这个有点意思,也make sense,因为是 divide & conquer 中的 divide 策略 确定了第一个搜索范围。