java 矩陣查找

  //忽略代碼風格...大小寫比較隨意了  
  private static final int[][] matrix = {
            {1, 2, 4, 5, 6, 7},
            {3, 4, 7, 8, 9, 10},
            {4, 5, 8, 12, 14, 16},
            {4, 6, 9, 14, 15, 17},
    };

    /**
     * 在二維數組中查找某個數是否存在
     * 次二維數組橫向與縱向都是單調遞增的
     */
    public static boolean testFindValueInMatrix01(int[][] matrix, int key) {
        Log.i("testFindValueInMatrix", "testFindValueInMatrix01 key=" + key);
        int rowCount = matrix.length;
        int columnCount = matrix[0].length;
        if (key < matrix[0][0]) {
            return false;
        } else if (key > matrix[matrix.length - 1][matrix[0].length - 1]) {
            return false;
        } else {
            for (int i = 0; i < rowCount; i++) {
                Log.i("testFindValueInMatrix", "testFindValueInMatrix01 i=" + i);
                if (key > matrix[i][columnCount - 1] || key < matrix[i][0]) {
                    Log.i("testFindValueInMatrix", "testFindValueInMatrix01 continue");
                    continue;
                } else {
                    for (int j = columnCount - 1; j >= 0; j--) {
                        if (key == matrix[i][j]) {
                            Log.i("testFindValueInMatrix", "testFindValueInMatrix01 find it "+"("+i+","+j+")");
                            return true;
                        }
                    }
                }

            }
        }
        return false;
    }
01-13 13:00:56.284 28607-28607/? I/testFindValueInMatrix: testFindValueInMatrix01 key=14
01-13 13:00:56.284 28607-28607/? I/testFindValueInMatrix: testFindValueInMatrix01 i=0
01-13 13:00:56.284 28607-28607/? I/testFindValueInMatrix: testFindValueInMatrix01 continue
01-13 13:00:56.284 28607-28607/? I/testFindValueInMatrix: testFindValueInMatrix01 i=1
01-13 13:00:56.284 28607-28607/? I/testFindValueInMatrix: testFindValueInMatrix01 continue
01-13 13:00:56.284 28607-28607/? I/testFindValueInMatrix: testFindValueInMatrix01 i=2
01-13 13:00:56.284 28607-28607/? I/testFindValueInMatrix: testFindValueInMatrix01 find it (2,4)
思路:

1.先與左上角的數字and 右下角的數字 對比,如果不在範圍內直接false;

2.與第一行最左 and最右的數字對比,不在範圍內,直接continue換下一行;

3.如果‘可能’在行內,那麼遍歷這一行;

4.如果不在行內,進行下一行的遍歷;


ps:還有更好的方式,待續

方法2:

public static boolean testFindValueInMatrix03(int[][] matrix,int key){
        int i = 0, j = matrix[0].length - 1;
        int var = matrix[i][j];
        while (i < matrix.length && j >= 0){
            if (var == key) {
                Log.i("testFindValueInMatrix", "testFindValueInMatrix03 find it " + "(" + i + "," + j + ")");
                return true;
            }else if (var < key) {
                var = matrix[++i][j];
            }else {
                var = matrix[i][--j];
            }
        }
        return false;
    }

網上有人叫上面這個方法是‘定位法’,這個方法其實是前一個方法的變種,從右上角那個數開始比較,如果右上角的數比key大,那麼就向左走,如果右上角的數比key小,就向下走;拿14爲例,右上角的數比14小,所以一路向下走到第三行,16比14大,想走走,14剛好找到。

方法3:

採用遞歸+二分法 的方式。

public static boolean testFindValueInMatrix02(
            int left,
            int right,
            int top,
            int bottom,
            int[][] matrix,
            int key) {
        Log.i("testFindValueInMatrix", "testFindValueInMatrix02 key=" + key);
        int midCol =  (left+right)>>1;
        int midRow =  (top+bottom)>>1;
        Log.i("testFindValueInMatrix", "testFindValueInMatrix02 left="+left+
                "--right="+right+
                "--top="+top+
                "--bottom="+bottom+
                "--midCol="+midCol+
                "--midRow="+midRow);
        Log.i("testFindValueInMatrix", "testFindValueInMatrix02 midValue=" + matrix[midRow][midCol]);
        if(left>right || top>bottom || midCol > right || midRow > bottom){
            return false;
        }
        if(key > matrix[bottom][right]){
            return false;
        }else if(key < matrix[top][left]){
            return false;
        }else{

            if(key>matrix[midRow][midCol]){
                return testFindValueInMatrix02(
                        midCol+1,
                         right,
                        midRow+1,
                        bottom,
                        matrix,
                        key) ||
                        testFindValueInMatrix02(
                                midCol+1,
                                right,
                                top,
                                midRow,
                                matrix,
                                key) ||
                        testFindValueInMatrix02(
                                left,
                                midCol,
                                midRow+1,
                                top+bottom,
                                matrix,
                                key);
            }else if (key<matrix[midRow][midCol]){
                return testFindValueInMatrix02(
                        left,
                        midCol-1,
                        top,
                        midRow-1,
                        matrix,
                        key) ||
                        testFindValueInMatrix02(
                                midCol,
                                right,
                                top,
                                midRow-1,
                                matrix,
                                key) ||
                        testFindValueInMatrix02(
                                left,
                                midCol-1,
                                midRow,
                                bottom,
                                matrix,
                                key);
            }else{
                Log.i("testFindValueInMatrix", "testFindValueInMatrix02 find it "+"("+(midRow)+","+(midCol)+")");
                return true;
            }
        }
    }

這個方法我簡單測試,是沒問題的。思路就是:根據二分法查看key在哪個區域,然後在那個區域回調查找,如圖:



例如第一個mid位置的值是7,查找14,14>7,那麼就在A,B,C三個區域再次查找。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章