1.二维数组中的查找
思路1:
使用暴力算法依次遍历进行比较,但是时间复杂度为O(n²),比较高。
//暴力查找二维数组中的目标数
public class Solution {
//找到目标数方法
public boolean Find(int target, int [][] array) {
if (array == null || array[0].length == 0) return false;
for (int[] arr:array) {
for (int val : arr) {
if (val == target) {
return true;
}
}
}
return false;
}
}
思路2:
因为从上到下、从左到右依次有序递增,那么可以使用二分查找的思路来进行解决,但是不能用以前的那种二分查找的方式:因为按照规则来说,可能出现arr[0] [3] >arr[3] [2],或者arr[0] [3] <arr[3] [2],因此不能进行顺序的二分查找。要重新思考怎么才能使用二分查找的思路来解决该问题。
改变方案:
1、设置初始值arr[row] [col]为右上角元素,即row = 0,col = arr.length - 1。
2、设置循环条件:当满足row < arr.length && 0 <= col (设置原因在循环判定中)。
3、在循环中进行判定:
- target == arr[row] [col],直接返回true。
- target < arr[row] [col],那么target在当前目标数arr[row] [col]的左边,需要col - 1,继续循环。
- target > arr[row] [col],那么target在当前目标数的下一行,因此row + 1,继续循环。
在循环中的判定过程中,可以看到,如果不满足条件,col只会向左移动,因此0 <= col 防止越界。row只会向下移动,因此row < arr.length防止越界。
复杂度分析:
时间复杂度:O(m+n),m为行数,n为列数。
空间复杂度:O(1)
代码实现:
//二分查找思路解决查找二维数组中的目标数
public class Solution{
//找到目标数方法
public boolean Find(int target, int [][] array) {
if (array == null || array[0].length == 0) return false;
//设置初始值为右上角元素
int row = 0, col = array.length - 1;
while (row < array.length && 0 <= col) {
if (array[row][col] == target) {
return true;
} else if (array[row][col] > target) {
col--;
} else {
row++;
}
}
return false;
}
}