小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
搜索二维矩阵II
该题出自力扣240题——搜索二维矩阵(中等题),题解是自己做的
审题
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:
每行的元素从左到右升序排列。 每列的元素从上到下升序排列。
-
题目的本意是在一个二维数组里面寻找出target目标值
-
考虑到该二维数组类似数独,从上而下和从左到右是升序的,可以有几种方式
-
(√)方法一:暴力遍历
- 直接双重for循环,遍历整个数组,在最里层判断并输出
- 时间复杂度O(m*n),空间复杂度O(1)
-
(√)方法二:二分查找
- 由于是有序的,所以可以采用二分查找,对于每一列或者每一行进行二分查找。
-
(√)方法三:抽象BST
- 也就是官方题解里面的Z解法,主要看怎么理解了;也可以理解成二叉搜索树(BST);
- 二叉查找树——左子树一定比根节点小,右子树一定比根节点大;
- 可以把首节点设置在矩形的右上角,也就是数组的
[0][j-1],比目标值大则列 - 1;小则行 +1; - 时间复杂度O(m+n),因为行最多移动m次,列最多移动n次;空间复杂度O(1)
编码
- 在最开始的时候,虽然想到了抽象BST的方法,但是却太片面了,没有想到可以从右上角直观地实现查找树原理。
- 所以一开始走了弯路,从最上角
[0,0,]开始,就需要比较很多不必要的东西,需要获取下一行和右边下一列的值,去比较两个值谁更大决定移动哪里;在这个的前提下,需要对i+1和j+1做边界判断,需要做了更多的无用功,导致实现的超时等
public static boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length;
int n = matrix[0].length;
int i = 0;
int j = n -1;
while (m>i && j>=0){
if (matrix[i][j] < target){
i++;
}else if (matrix[i][j] > target){
j--;
}else {
return true;
}
}
return false;
}