1. 程式人生 > >一天一演算法 day1--二維陣列中查詢

一天一演算法 day1--二維陣列中查詢

二維陣列中查詢

致2019

2018年就這樣匆匆過去,這一年過得太單調,太平凡,每天上班下班,日復一日。偶爾學些所謂的新技術,良心發現不能懶惰就會啃幾天書。雖然自己平時也會零零散散的寫一些技術日誌,記錄下開發過程中遇到的困難,但都是隨手記錄的方式,寫完就躺在筆記軟體裡了,也沒有很好的整理,它們重見天日的機會渺茫,因為都在腦子裡了啊,哈哈。從大學到現在幾年之中,已經嘗試過好幾次搭建自己的部落格,不過搭完也就完了,有自己搭vps,gitbub,部落格園等等,甚至CSDN的部落格也是從2015年就已經註冊了的,但是沒有一個堅持下來。這段時間在看《劍指offer》,裡面的題目和解題思路都非常不錯,但是原書基於C/C++實現的。我只能自己用java寫一遍,寫得對不對,好不好也沒人知道,寫完也沒有整理記錄。於是萌生了一個將java的實現通過部落格來公佈,一是供朋友們參考學習;二是希望有人交流溝通,能發現些什麼問題。三是監督自己堅持寫部落格,作為2019的一個小目標吧。

好了下面進入今天的主題。

本題程式碼已上傳到:gitbub

題目

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

題目分析

這題相對簡單,就是一個矩陣搜尋問題。就是從一個角開始搜尋(右上/左下)。因為矩陣是有序的,在右上/左下的數字,必定是這行或這列的極值(最大或最小值),只要通過一次比較,那必定能排除一行或一列,通過不斷迴圈,很快就能找到結果。

圖2的流程很形象的解釋瞭解題邏輯,比如搜尋整數7,本題是遞增序列,那麼如果我們從右上角開始,右上角的9,是9所在行的最大值,是9所在列的最小值,只要和給定的數字7比較大小,就知道可以去掉一行或一列了,這裡是去掉9所在的第四列。然後進入下次迴圈,一直比較直到找到數字返回true,或者矩陣為空返回false。

圖2:圖2

那麼為什麼不從中間開始呢,看看下邊圖3就大致理解了,這個書中的解法裡其實有個降維的思想。如果從矩陣中間開始搜尋,除邊角外任何一個位置都會有4個方向,雖然通過比較,能去掉一個角(圖中白色),表面看起來是去掉了2個方向,但是移動比較位置後又會有4個方向(或3個),無窮無盡,也許最後能找到結果,但是程式的邏輯會變得非常複雜(幾個方向意味著幾次比較和幾個可能),而本題的解法,直接從4個方向降為2個方向,直接簡化了判斷邏輯,且縮小後的矩陣依然符合程式的判斷邏輯。

圖3:圖3

程式碼實現

 private static boolean checkMatrix(int[][] matrix,
int num) { boolean exist = false; if (matrix != null && matrix.length > 0 && matrix[0].length > 0) { // TODO 這裡省略對每行長度的檢查,只是簡單從第1行判斷是否為空,如果考慮健壯性,是需要檢查的,不在本題的考察範圍 int row = matrix.length; int col = matrix[0].length; for (int i = 0, j = col - 1; i < row && j >= 0; ) { if (matrix[i][j] == num) { exist = true; break; } else if (matrix[i][j] > num) { j--; } else { i++; } } } else { System.out.println("matrix is empty"); } return exist; }

測試用例

public static void main(String[] args) {
        int[][] matrix = {
                {1, 2, 8, 9, 11},
                {2, 4, 9, 12, 13},
                {4, 7, 10, 13, 16},
                {6, 8, 11, 15, 21}};

        int num1 = 1;
        System.out.println(num1 + " in matrix is " + checkMatrix(matrix, num1));
        int num2 = 21;
        System.out.println(num2 + " in matrix is " + checkMatrix(matrix, num2));
        int num3 = 16;
        System.out.println(num3 + " in matrix is " + checkMatrix(matrix, num3));
        int num4 = 0;
        System.out.println(num4 + " in matrix is " + checkMatrix(matrix, num4));
        int num5 = 30;
        System.out.println(num5 + " in matrix is " + checkMatrix(matrix, num5));
        int num6 = 3;
        System.out.println(num6 + " in matrix is " + checkMatrix(matrix, num6));

        int num = 4;
        matrix = null;
        System.out.println(num + " in matrix is " + checkMatrix(matrix, num));

    }

測試結果

1 in matrix is true
21 in matrix is true
16 in matrix is true
0 in matrix is false
30 in matrix is false
3 in matrix is false
matrix is empty
4 in matrix is false