《劍指offer》Java學習錄:數組(面試題3:二維數組中的查找)

數組

佔據了內存中一段連續的內存空間,並順序存儲,因此可以通過數組下標直接訪問,時間複雜度爲O(1)O_{(1)},時間效率高。在申明一個數組時,即使不往數組內存數據,也需要給定數組的空間大小。數組的這種存儲方式,造成了內存空間的浪費,經常會有空間沒有得到有效利用。

爲了解決數組空間利用率的問題,在各大高級語言中,設計了動態數組。

所謂的動態數組指的是,在初始狀態下會有一個默認長度的數組,往動態數組中添加數據時,如果超過了默認數組的容量,動態數組會重新申請一個數組(該數組的大小通常是當前數組容量的兩倍),然後將已有數據拷貝(頻繁的拷貝會影響效率)到新數組,最後釋放舊數組。以此達到提高空間利用率的目的。

java中底層是動態數組機制的有:ArrayList,Vector和Stack。

面試題 3:二維數組中的查找

題目

在一個二維數組中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,輸入這樣一個二維數組和一個整數,判斷數組中是否含有該整數。

下面數組就是每行、每列遞增排序,如果查找數字77,能找到,函數返回true,如果查找數字55,因爲數組中沒有該數字,無法找到,所以函數返回false
128924912471013681115 \begin{matrix} 1& 2& 8& 9 \\ 2& 4& 9& 12 \\ 4& 7& 10& 13 \\ 6& 8& 11& 15 \end{matrix}

分析

不知道爲啥,剛看完題目,最直接的反應是直接雙循環遍歷不就好了。甚至覺得這個題出得沒有必要。直到看完案例分析才意識到圖樣圖森破。

該題考察的是算法邏輯,如果無腦遍歷的話,確實可以實現功能,但效率會變得很低。最糟糕的情況,會將數組矩陣中所有元素都遍歷比較一次才能得到結果。

提高效率的解法是從行和列都是遞增着手,首先明確一點就是,每行的最後一個元素,是當前行的最大值,是當前列的最小值

那麼核心邏輯便是:首先取第一行最後一列元素(後面稱爲數組元素),與目標值(以後稱爲target_number)作對比。

如果數組元素大於target_number,因爲數組元素是該列第一個元素,且矩陣行列遞增,數組元素爲該列最小值,說明數組元素所在列不可能出現target_number,刪掉當前列(在後續的查找過程中,不考慮該列)。

如果數組元素小於target_number,因爲數組元素是該列第一個元素,且矩陣行列遞增,數組元素爲該行最大值,說明數組元素所在行不可能出現target_number,刪掉當前行(在後續的查找過程中,不考慮該行)。

比如在示例矩陣中,首先比較右上角的數字99,目標數字爲44,那麼應該刪除當前列,我們需要考慮的矩陣將變成這樣:
12824947106811 \begin{matrix} 1& 2& 8 \\ 2& 4& 9 \\ 4& 7& 10 \\ 6& 8& 11 \end{matrix}
接着用目標數字44和右上角數組元素88比較,數組元素還是大於目標數字,應該刪掉當前列,矩陣變爲:
12244768 \begin{matrix} 1& 2 \\ 2& 4 \\ 4& 7 \\ 6& 8 \end{matrix}
繼續用目標數字44和右上角數組元素22比較,數組元素還是小於目標數字,應該刪除當前行,矩陣變爲:
244768 \begin{matrix} 2& 4 \\ 4& 7 \\ 6& 8 \end{matrix}
最後,右上角數組元素是44,和目標數字相等,返回true。

解:C++

#include <iostream>

using namespace std;

const int maxRow = 4;
const int maxColumn = 4;

bool searchValue(int number, int array[maxRow][maxColumn]) {
    int row = 0;
    int column = maxColumn - 1;
    while (row < maxRow && column >= 0) {
        if (array[row][column] > number) {
            column--;
        } else if (array[row][column] < number) {
            row++;
        } else {
            return true;
        }
    }
    return false;
}

int main() {
    int array[maxRow][maxColumn] = {{1, 2, 8,  9},
                                    {2, 4, 9,  12},
                                    {4, 7, 10, 13},
                                    {6, 8, 11, 15}};
    bool result = searchValue(14, array);
    cout << "result = " << (result ? "true" : "false") << endl;
    return 0;
}

解:java

public class InterviewQuestion3 {
    public static void main(String[] args) {
        int[][] array = {
            {1, 2, 8, 9},
            {2, 4, 9, 12},
            {4, 7, 10, 13},
            {6, 8, 11, 15}};
        boolean result = searchValue(7, array);
        System.out.println("result = " + result);
    }

    private static boolean searchValue(int number, int[][] array) {
        int maxRow = array.length;
        int maxColumn = array[0].length;
        int row = 0;
        int column = maxColumn - 1;
        while (row < maxRow && column > 0) {
            if (array[row][column] > number) {
                column--;
            } else if (array[row][column] < number) {
                row++;
            } else {
                return true;
            }
        }
        return false;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章