題目:在一個二維數組中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。
例如下面的二位數組就是每行每列都遞增排序。如果在這個數組中查找數字7,則返回true;如果查找數組5,由于數組不含有該數字,則返回false。
1 2 8 9
2 4 9 12
4 7 10 13
6 8 11 15
分析
在分析這個問題的時候,很多應聘者會把二維數組畫成矩形,從數組中選取一個數字,分3種情況來分析查找的過程,當數組中選取的數字剛好和要查找的數字相等時,就結束查找過程,如果選取的數字小于要查找的數字,那么根據排序的規則,要查找的數字應該在當前選取的位置的右邊或者下邊。
那么問題來了
由于要查找的數字相對于當前選取的位置有可能在兩個區域中出現,而且這兩個區域還有重疊,問題看起來就復雜了。
換一種分析方法
這里分析一個復雜的問題時,一個很有效的辦法就是從一個具體問題入手,通過簡單的分析,找出規律。
** 前面我們之所以遇到問題,是因為我們在二維數組的中間選取一個數字來和要查找的數字做比較,這樣導致下一次要查找的是兩個相互重疊的區域。如果我們從數組的一個角上選取數字來和要查找的數字做比較,情況會不會好一點? **
首先我們選取數組右上角的數字9,因為7<9,9的縱向一列都大于9,所以9所在的一列都一定比7大,這樣就可以把這列從數組中去掉。接下來到了8,8<9,繼續去掉8所在的一列,到了2,2>7,此時2所在的行中,2是最大的,最大的還小于7,所以這行所有元素均小于7,所以去掉2所在的這樣,到了4,4也小于7,同理,去掉4所在的一行。最終找到了7.
總結規律
那么規律貌似可以總結出來了,我們每次要查找一個數字b,可以從二維數組中的右上角的數a查找,如果a<b,則去掉a所在的行,如果a>b,則去掉a所在的列。就這樣一直查找,直到數組中沒有元素為止。
實現代碼如下
bool Find(int *martix,int rows,int column,int number) { bool flag = false; int row=0; int col=column-1; if(martix!=NULL&&rows>0&&column>0) { while (row<rows&&col>=0) { if(martix[row*column+col]==number) { flag = true; break; } else if (martix[row*column+col]>number) col--; else if (martix[row*column+col]<number) row--; } } return flag; }