【題目】 給定一個有N*M的整形矩陣matrix和一個整數K,matrix的每一行和每一列都是排好序的。實現一個函數判斷K是否在matrix中。例如:
0 1 2 5
2 3 4 7
4 4 4 8
5 7 7 9
如果K爲7,則返回true;如果K爲6,返回false。
要求: 時間複雜度爲O(N+M),額外空間複雜度爲O(1)。
【解答】
可以將問題抽象成下面的模型:
數字越大,顏色越深,給了一個灰色方塊,讓你找到這個顏色的方塊位於哪裏
查找的這個方塊應該從右上或者左下開始走,逐一對比。在任意時刻可以簡化出這樣一個模型:
即:同一時刻,往下走更黑,往左走更白。根據自己與當前位置方格顏色比較,決定走向更白還是更黑的地方
1)如果顏色相同則找到了。
2)如果自己的顏色比此位置方塊淺,那麼向左走,因爲向下只會更黑
3)如果自己的顏色比此位置方塊深,那麼應該向下走,走向更黑的地方去比較。
爲什麼不能從左上角或者右下角開始走?
因爲那樣用不了排除法。只能一個一個比較(O(n))。假如從左上角開始對比顏色,往右和往下都是變得更黑,所以不知道應該往哪裏走。同樣右下角開始,往上和往左都是變淺。還是不知道往哪裏走。而我們要構建的就是在對角線上這種“非黑即白”的感覺,才能做出確定的選擇。
/**
*從排好序的矩陣中找數,每一行和每一列都排好序
* @author liq
*
*/
public class Code09_FindNumInSortedMatrix {
public static boolean isContains(int[][] matrix, int num) {
//開始位置:右上角
int row = 0;
int col = matrix[0].length - 1;
while (row <= matrix.length-1 && col >= 0) {//不超過邊界
if (num == matrix[row][col]) { //直接命中
return true;
}else if (num < matrix[row][col]) { //自己顏色比當前淺,向左走,因爲向下更黑
col --;
}else { //自己顏色比當前顏色深,向下走向更黑的地方
row ++;
}
}
return false;
}