[leetcode] Search a 2D Matrix II

  • Question : 

    Search a 2D Matrix II

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

    • Integers in each row are sorted in ascending from left to right.
    • Integers in each column are sorted in ascending from top to bottom.

    For example,

    Consider the following matrix:

    [
      [1,   4,  7, 11, 15],
      [2,   5,  8, 12, 19],
      [3,   6,  9, 16, 22],
      [10, 13, 14, 17, 24],
      [18, 21, 23, 26, 30]
    ]
    

    Given target = 5, return true.

    Given target = 20, return false.

    • 群暉面試考題
  • idea : 
    • 假設 m 是 row, n 是 column
    • 這是一個楊氏矩陣,由1900年, 劍橋大學數學家Young tableau 所提出。
    • 談到搜尋法 就不得不提最常考的Binary Search這應用很廣。
    1. (Binary Search) :
        直接對每row都各別做Binary Search.則Time complexity: O(m*lgn)
    2. (walk-wise) :
      觀察楊氏矩陣特性, 發覺每一個矩陣的元素,都小於其下column的元素,且都大於其左row的元素。
      因此,我們可以選從右上角開始走訪。當target > matrix[m][n], 我們忽略 matrix[m][0] ~  matrix[m][n]。
      也就是matrix[m][n]的左列元素,往下走訪。當target < matrix[m][n], 忽略matrix[m][n] ~ matrix[col-1][n], 往左走。
      Time complexity : O(m+n)

      舉例上圖來說,最右上角是15. 其左邊同列1, 4, 7, 11 皆小於15,但下面同行19, 22, 24, 30皆大於15
      假設target = 13, 所以我們必須往左走。忽略正下方的這行。
    3. 四分法:
      採用Divide and conquer, 每次砍1/4的matrix
      Time Compexity : 

      T(n) = 3 * T(n/4) + c

      which leads to

      T(n) = O(n^log4(3)) = O(n^0.7925)
      發覺跟上個方法的time compexity 無法比較, 因為上個方法的input data size 是基於matrix : m*n
      而這次的n是基於整個matrix總共有幾個數字。
      所以我們再次用matrix的行列個數來求time compexity, 好讓各解法的時間複雜度都在同一個起點。
      Here T(n) defines a problem on a matrix with size n x n.
      Similarly T(n/2) should define a problem on a matrix with size n/2 x n/2.
      when you divide the matrix in 4 parts that gives you 4 matrices with size n/2 x n/2.
      So each sub problem is T(n/2).
      所以為了比較方面我們改寫成:T(n) = 3T(n/2) + c. By master's theorem
      T(n)=O(n^1.58)

    4. 二分法:
      比四分法更好的是,我們只需要分別對兩個sub-matrix with n/2 x n/2. 做運算。而四分法需對三個。
      T(n) = 2T(n/2)+cn, 其中cn是針對中間行,或中間列,或對角線上元素做運算之成本
      O(n lg n)
    5. 改進二分法:
      二分法中,cn的部分是線性掃描時間,改用binary search
      T(n) = 2T(n/2)+c*lgn, 因為lgn > n 不能用master's theorem
      疊代法得T(n) = O(n)

  • Code :
       [walk-wise]
    • bool searchMatrix(int** matrix, int matrixRowSize, int matrixColSize, int target) {
          int m = 0;
          int n = matrixColSize-1;
          while(n>=0 && m <= matrixRowSize -1 ) {
              if(matrix[m][n] > target)
                  n--;
              else if (matrix[m][n] < target)
                  m++;
              else 
                  return true;
          }
          return false;
      }
      
  • 心得:面試考題,大多可以延伸,或者可以有很多種作法。重點是白板應該不會考太長的。
    • 另外,群暉面試時有問到如何傳回i,j值。也就是第幾行第幾列。我的想法是 return &matrix[m][n] - &matrix[0][0]; 到main() 時
      i = searchMatrix(...) / matrixColSize;
      j = searchMatrix(...)% matrixColSize;
    • C is row-major
  • see also :
    • search a 2d matrix 
    • http://blog.csdn.net/sgbfblog/article/details/7745450
    • http://articles.leetcode.com/2010/10/searching-2d-sorted-matrix-part-ii.html
posted @ 2015-08-19 13:09  jeremyatchina  阅读(335)  评论(0编辑  收藏  举报