Search a 2D Matrix

Question:數組

Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:ide

  • Integers in each row are sorted from left to right.
  • The first integer of each row is greater than the last integer of the previous row.

For example,測試

Consider the following matrix:spa

[
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]

Given target = 3, return true.指針

Solution:code

    看到這個題目的第一想法是先對最右邊一列作二分查找,定位是在哪一行,而後在這一行作二分查找。時間複雜度是O(logm)+O(logn)=O(logm+logn)=O(log(m*n))。blog

    這樣須要兩次二分查找,其實一次就能夠了。把二維數組轉化爲一維數組。從左向右,從上向下依次取出每一個元素,那麼這些元素是總體有序的,能夠看做一個一維數組,用二分查找解決。時間複雜度是O(log(m*n)),和上面的同樣。ci

    開始實現這個二分查找代碼的時候,begin和end記錄的是兩個點,這樣代碼寫起來較複雜,見註釋中的代碼。後來begin和end改成轉化爲一維數組後的下標,這樣就簡單多了。代碼以下,在leetcode上測試經過了。leetcode

class Solution {
public:
    bool searchMatrix(vector<vector<int> > &matrix, int target) {
        if (matrix.size() == 0)
            return false;
        int col_len = matrix[0].size();
        int row_len = matrix.size();
        int beg = 0;
        int end = row_len * col_len - 1;
        while (beg <= end) {
            int mid = beg + (end - beg) / 2;
            int k = matrix[mid/col_len][mid%col_len];
            if (target == k)
                return true;
            else if (target > k)
                beg = mid + 1;
            else
                end = mid - 1;
        }
        /* 
         * the following is another way, but more complex
         *
        int beg_row = 0;
        int beg_col = 0;
        int end_row = row_len - 1;
        int end_col = col_len - 1;
        while (end_row * col_len + end_col >= beg_row * col_len + beg_col) {
            int total = col_len - beg_col + end_col + 1 + col_len * (end_row - beg_row - 1);
            int k_col = (beg_col + (total / 2) % col_len) % col_len;
            int k_row = beg_row + (beg_col + (total / 2)) / col_len;
            if (target == matrix[k_row][k_col])
                return true;
            else if (target > matrix[k_row][k_col]) {
                beg_row = k_row + (k_col + 1) / col_len;
                beg_col = (k_col + 1) % col_len;
            } else {
                end_row = (k_col == 0) ? k_row - 1 : k_row;
                end_col = (k_col == 0) ? col_len - 1 : k_col - 1;
            }
        }
        */
        return false;
    }
private:
};

    這個題目讓我想起了另一個二維數組題目,二維數組每一行,從左到右有序,每一列,從上到下有序,也是查找一個數。方法是從右上角的元素開始比較大小,指針向下或向左移動,時間複雜度是O(m+n)。get

相關文章
相關標籤/搜索