1. 程式人生 > >每天一題之001

每天一題之001

我們 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