題目:一個橫縱向均遞增的矩陣,指定元素是否在矩陣中?測試
看網上討論很多,就是沒個正經答案——沒有測試過的代碼沒有完整的理論。spa
如今給出個人分析:假設矩陣是m*n的,給定元素爲e。code
思路一:對矩陣每行(或每列)進行二分搜索,複雜度爲 O(nlog2m)或O(mlog2n)。blog
思路二:將二分搜索推廣到矩陣。參照下面矩陣,找到矩陣的中間數a32,比較a32和e會有以下狀況:element
如此,可知每次迭代都將數據量減小爲原來的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 }