題目描述:
在一個(gè)二維數(shù)組中(每個(gè)一維數(shù)組的長(zhǎng)度相同)喻括,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請(qǐng)完成一個(gè)函數(shù)慌随,輸入這樣的一個(gè)二維數(shù)組和一個(gè)整數(shù),判斷數(shù)組中是否含有該整數(shù)躺同。
看著有點(diǎn)懵逼阁猜,不如在紙上先畫(huà)出圖形,先初始化一組數(shù)組蹋艺,int [ 4 ] [ 4 ]剃袍,大概如下:
從題目要求可知道,要輸入一個(gè) target 车海,也就是目標(biāo)數(shù)字笛园,去二維數(shù)組中查找,是否存在侍芝,如果存在就返回 true 研铆,不存在返回 false。
怎么查找呢州叠?
大家有沒(méi)有發(fā)現(xiàn)棵红,這組二維數(shù)組的規(guī)律,每一行從左到右遞增咧栗,每一列從上到下遞增逆甜。
根據(jù)這個(gè)特點(diǎn)來(lái)查找,不知道大家有沒(méi)有玩過(guò)“吃雞”游戲致板,聰明的玩家喜歡邊緣 OB 交煞,在毒圈邊界中活動(dòng)。那么這個(gè)算法的核心也如此斟或。
從每一行看素征,右上角的數(shù)字是該行的最大數(shù)字;
從每一列上看,右上角數(shù)字是該列的最小值御毅;
關(guān)鍵點(diǎn)就是取數(shù)組右上角的數(shù)字根欧,來(lái)與 target 比較;
如果第一行右上角的數(shù)字端蛆,剛好等于 target 凤粗,那么查找結(jié)束,返回 true今豆;
如果 target 小于 數(shù)組右上角數(shù)字嫌拣,那么這個(gè)右上角數(shù)字所在的列可以排除掉了(因?yàn)樗诹惺且来芜f增的);
如果 target 大于 數(shù)組右上角數(shù)字晚凿,那么可以排除右上角數(shù)字所在行了亭罪;(原理同上)
就這樣依次邊緣 OB,縮小毒圈歼秽,成功吃雞应役!
舉個(gè)例子:
假設(shè)我現(xiàn)在要找的 target 是 7,要在二維數(shù)組中查詢(xún)燥筷,第一次查詢(xún)即如下:
第二次查詢(xún)
第三次查詢(xún)
核心代碼如下:
public boolean Find(int target, int [][] array) {
if (array == null || array.length ==0 || array[0].length == 0) {
return false;
}
int rows = array.length;//行數(shù)
int columns = array[0].length;//列數(shù)
if (target > array[rows - 1][columns - 1] || target < array[0][0]) {
return false;
}
rows = 0;
for (int i = columns - 1; i >= 0 && rows < array.length; ) {
if (array[rows][i] == target) {
return true;
}
if (target < array[rows][i]) {
i--;
continue;
}
if (target > array[rows][i]) {
rows++;
continue;
}
}
return false;
}
參考文獻(xiàn):
https://blog.csdn.net/u010002184/article/details/79518961
https://www.nowcoder.com/questionTerminal/abc3fe2ce8e146608e868a70efebf62e