【原創】橫縱遞增矩陣搜索

題目:一個橫縱向均遞增的矩陣,指定元素是否在矩陣中?測試

看網上討論很多,就是沒個正經答案——沒有測試過的代碼沒有完整的理論。spa

如今給出個人分析:假設矩陣是m*n的,給定元素爲e。code

思路一:對矩陣每行(或每列)進行二分搜索,複雜度爲 O(nlog2m)或O(mlog2n)。blog

思路二:將二分搜索推廣到矩陣。參照下面矩陣,找到矩陣的中間數a32,比較a32和e會有以下狀況:element

  1. a32 == e,找到
  2. a32 > e,排除矩陣(a32, a64),由於這個區域數據必定比e大
  3. a32 < e,排除矩陣(a00, a32),由於這個區域數據必定比e小

如此,可知每次迭代都將數據量減小爲原來的3/4,如此複雜度爲O(log4/3 (m*n)),約爲O(log2 (m*n))class

a00 a01 a02 a03 a04搜索

a10 a11 a12 a13 a14數據

a20 a21 a22 a23 a24static

a30 a31 a32 a33 a34di

a40 a41 a42 a43 a44

a50 a51 a52 a53 a54

a60 a61 a62 a63 a64

具體代碼以下,已通過測試,單元素、單行、單列等均經過測試。寫得不很簡潔,有意見儘管提。

 1 public class IncreasingMatrixSearch {
 2 
 3     public static boolean find(int[][] M, int x1, int y1, int x2, int y2, int e){
 4         if(x1 == x2 && y1 == y2) // only one element
 5             return M[x1][y1] == e;
 6         if(x2-x1 <= 1 && y2-y1 <= 1) // smallest cubic
 7             return (M[x1][y1] == e || M[x2][y1] == e || M[x2][y2] == e || M[x1][y2] == e);
 8         
 9         if(e < M[x1][y1] || e > M[x2][y2])
10             return false;
11         
12         int xm = (x1 + x2)/2;
13         int ym = (y1 + y2)/2;
14         
15         boolean exist = false;
16         if(M[xm][ym] == e)
17             return true;
18         if(M[xm][ym] > e)
19             exist = find(M, x1, y1, xm, ym, e);// search up-left
20         else
21             exist = find(M, xm, ym, x2, y2, e);// search down-right
22         if(!exist){
23             return (find(M, x1, ym+1, xm-1, y2, e) || find(M, xm+1, y1, x2, ym-1, e)); 
24         }
25         
26         return exist;
27     }
28 }
相關文章
相關標籤/搜索