题目:在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例:
现有矩阵 matrix 如下:
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
给定 target = 5,返回 true。
给定 target = 20,返回 false。
题目分析:
思路一: 首先想到的是通过遍历整个数组,看是否存在这样一个与目标值相等的元素,如果有返回true, 如果没有返回false。
思路二:思路一是暴力的方法,时间复杂度为 O ( n 2 ) O({n^2}) O(n2),没有充分利用从左到右从上到下递增 这一条件。
第一步: 根据观察,我们需要先从数组的右上角出发,如果目标值比当前元素大,目标值如果存在的话,一定在当前元素的左边。如果目标值比当前元素小,目标值如果存在的话,一定在当前元素的下边。每次移动位置可以过滤一行或者一列。如此循环即可。
(从数组的左下角出发也是可以的)
第二步:循环条件。通过下移后,发现行数索引值已经超过数组本身行数,或者通过左移,发现列数索引值小于0。
Java代码:
import java.util.Arrays;
public class Offer04 {
public static void main(String[] args) {
int[][] array = {
{1, 4, 7, 11, 15},
{2, 5, 8, 12, 19},
{3, 6, 9, 16, 22},
{10, 13, 14, 17, 24},
{18, 21, 23, 26, 30},
{19, 22, 24, 27, 33},
{23, 29, 35, 36, 39}
};
System.out.println(f(array,29));
System.out.println(Arrays.toString(g(array,29)));
}
private static boolean f(int[][] array, int target) {
// 要先判断二维数组的有效性,这一步很重要
if (array == null || array.length == 0 || array[0].length == 0) {
return false;
}
int row = array.length; // 获取二维数组的行数
int col = array[0].length; // 获取二维数组的列数
// 从二维数组的右上角开始位置搜索。 array[0][col-1]
int i = 0;
int j = col-1;
// 使用while更好。
while (i<row && j>=0){
if(target<array[i][j]){
j--;
}else if(target>array[i][j]) {
i++;
}else {
return true;
}
}
return false;
}
// 该函数是我自用于得到目标值所在下标添加的。。
private static int[] g(int[][] array, int target) {
// 要先判断二维数组的有效性,这一步很重要
if (array == null || array.length == 0 || array[0].length == 0) {
return (new int[]{-1,-1});
}
int row = array.length; // 获取二维数组的行数
int col = array[0].length; // 获取二维数组的列数
// 从二维数组的右上角开始位置搜索。 array[0][col-1]
int i = 0;
int j = col-1;
//不能使用for循环,使用while更好。
while (i<row && j>=0){
if(target<array[i][j]){
j--;
}else if(target>array[i][j]) {
i++;
}else {
return (new int[]{i,j});
}
}
return (new int[]{-1,-1});
}
}
【注】
(1):leetcode 等平台只要我们完成一个函数即可,本人初出茅庐,为了巩固基本知识,故自己补充了部分代码,用于练手。
(2):一定要注意先判断数组是否为空,我自己搞了半个小时,最后发现因为没有对数组有效性进行判断这样的低级错误。