每天一題之001
阿新 • • 發佈:2017-11-06
我們 ray [0 args imp string public 兩個 void
題目描述:
在一個二維數組中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。
輸入:
輸入可能包含多個測試樣例,對於每個測試案例,
輸入的第一行為兩個整數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) ; } */ }
每天一題之001