1. 程式人生 > >LeetCode筆記——74搜尋二維矩陣

LeetCode筆記——74搜尋二維矩陣

題目

編寫一個高效的演算法來判斷 m x n 矩陣中,是否存在一個目標值。該矩陣具有如下特性:

  • 每行中的整數從左到右按升序排列。
  • 每行的第一個整數大於前一行的最後一個整數。

示例 1:

輸入:
matrix = [
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]
target = 3
輸出: true

示例 2:

輸入:
matrix = [
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]
target = 13
輸出:
false

程式碼一:網上大神的程式碼,包括程式碼一和程式碼二。原文連結:https://blog.csdn.net/DERRANTCM/article/details/47142931

思路:這個程式碼的思想是先利用二分法找到該數字可能在的行,然後利用二分查詢到可能在的列。

public class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return false;
        }
        int row = matrix.length;
        int column = matrix[0].length;
        int low = 0;
        int high = row - 1;
        int mid = 0;
        // 找結果所在的列
        while (low <= high) {
            mid = low + (high - low) / 2;
            if (target < matrix[mid][column - 1]) {
                high = mid - 1;
            } else if (target > matrix[mid][column - 1])  {
                low = mid + 1;
            }
            else
            { return true;
           }
        }
        // 決定列所在的最終位置
        int targetRow = mid;
        if (matrix[mid][column - 1] < target) {
            targetRow++;
        }
        // 目標列超出,無結果
        if (targetRow >= row) {
            return false;
        }
        low = 0;
        high = column - 1;
        // 找所在的行,找到返回true,沒有返回false
        while (low <= high) {
            mid = low + (high - low) / 2;
            if (target < matrix[targetRow][mid]) {
                high = mid - 1;
            } else if (target > matrix[targetRow][mid]) {
                low = mid + 1;
            } else
            { return true;
            }
        }
        return false;
    }
}


程式碼二:

以下是另一種思路的程式:

思路:將要查詢的數與矩陣右上角的數進行比較。如果該數大於要查詢的數,就刪除該數所在的那一列;如果該數小於要查詢的數,就刪除該數所在的那一行。

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
     
 
        // 輸入條件判斷
        if (matrix == null || matrix.length < 1 || matrix[0].length < 1) {
            return false;
        }
 
        int rows = matrix.length; // 陣列的行數
        int cols = matrix[0].length; // 陣列行的列數  這個很奇怪,原始程式碼是1,結果編譯出錯,改成0之後就通過了。。
 
        int row = 0; // 起始開始的行號
        int col = cols - 1; // 起始開始的列號
 
        // 要查詢的位置確保在陣列之內
        while (row >= 0 && row < rows && col >= 0 && col < cols) {
            if (matrix[row][col] == target) { // 如果找到了就直接退出
                return true;
            } else if (matrix[row][col] > target) { // 如果找到的數比要找的數大,說明要找的數在當前數的左邊
                col--; // 列數減一,代表向左移動
            } else { // 如果找到的數比要找的數小,說明要找的數在當前數的下邊
                row++; // 行數加一,代表向下移動
            }
        }
 
        return false;
    }
 
    }

執行最快的程式碼:

執行最快的程式碼看起來好像也是使用二分查詢的思想

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        if(null == matrix || matrix.length == 0 || matrix[0].length == 0){
            return false;
        }
        int lo = 0, hi = matrix.length - 1;
        while(lo <= hi){
            int mid = (lo+hi)/2;
            if(matrix[mid][0] == target){
                return true;
            }
            if(matrix[mid][0] > target){
                hi = mid - 1;
            }
            else{
                lo = mid + 1;
            }
        }
        if(lo > matrix.length || lo == 0){
            return false;
        }
        int row = lo - 1;
        lo = 0;
        hi = matrix[0].length - 1;
        while(lo <= hi){
            int mid = (lo+hi)/2;
            if(matrix[row][mid] == target){
                return true;
            }
            if(matrix[row][mid] < target){
                lo = mid + 1;
            }
            else{
                hi = mid - 1;
            }
        }
        return false;
    }
}