题目描述:
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
输入:
输入可能包含多个测试样例,对于每个测试案例,
输入的第一行为两个整数m和n(1<=m,n<=1000):代表将要输入的矩阵的行数和列数。
输入的第二行包括一个整数t(1<=t<=1000000):代表要查找的数字。
接下来的m行,每行有n个数,代表题目所给出的m行n列的矩阵(矩阵如题目描述所示,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
输出:
对应每个测试案例,
输出”Yes”代表在二维数组中找到了数字t。
输出”No”代表在二维数组中没有找到数字t。
样例输入:
3 3
5
1 2 3
4 5 6
7 8 9
3 3
1
2 3 4
5 6 7
8 9 10
3 3
12
2 3 4
5 6 7
8 9 10
样例输出:
Yes
No
No
分析:这个题目我们很容易想到一个时间复杂度为O(n^2)的算法,依次遍历每一个数组元素,与输入整数比较,如果相等则返回"Yes",否则返回“No”,这样做肯定会超时。
仔细分析题目,发现题目中这句话“每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序”很关键” ,二维数组中每一行是递增,每一列也是递增。但不是完全有序,例如
1 3 4 5
2 4 5 6
因此不能先找到行,在去找列,由于每一行的最后一个元素是最大的,如果输入元素大于该行的最后一个元素,则说明输入整数在下面几行中;如果输入整数小于该行的最后一个元素,则说明该元素在该列前面几列中。从而找到优化的算法,定义两个指示器一个行指示器,一个列指示器,初始值指向第一行的最后一列的元素。
Java实现如下:
import java.util.Scanner ; public class Solution { public boolean Find(int target, int [][] array) { int m = array.length ; int n = array[0].length ; int i = 0 ; int j = n-1 ; while(i<m && j>=0) { if(array[i][j]==target) return true ; else if(array[i][j]<target) { i++ ; } else { j-- ; } } return false ; } /** public static void main ( String [] args ) { Scanner in = new Scanner(System.in) ; int m = in.nextInt() ; int n = in.nextInt() ; int target = in.nextInt() ; int [][] array = new int[m][n] ; for(int rows = 0 ; rows < m ; rows ++) for(int columns = 0 ; columns < n ; columns ++ ) { array[rows][columns] = in.nextInt() ; } Solution solution = new Solution() ; solution.Find( target, array) ; } */ }