- 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
, returntrue
.Given target =
20
, returnfalse
.- 群暉面試考題
- idea :
- 假設 m 是 row, n 是 column
- 這是一個楊氏矩陣,由1900年, 劍橋大學數學家Young tableau 所提出。
- 談到搜尋法 就不得不提最常考的Binary Search這應用很廣。
- (Binary Search) :
直接對每row都各別做Binary Search.則Time complexity: O(m*lgn) - (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, 所以我們必須往左走。忽略正下方的這行。 - 四分法:
採用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) - 二分法:
比四分法更好的是,我們只需要分別對兩個sub-matrix with n/2 x n/2. 做運算。而四分法需對三個。
T(n) = 2T(n/2)+cn, 其中cn是針對中間行,或中間列,或對角線上元素做運算之成本
O(n lg n) - 改進二分法:
二分法中,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