題目描述:
在一個二維數組中(每個一維數組的長度相同),每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。
思路:
首先遍歷行,如果發現查找目標不在本行值域內,就移動到下一行。如果發現目標值在本行的值域內,則依次將本行的每一個元素與查找目標比對。相信和大多數的菜鳥思路一樣。但是寫完之後總感覺這種方法太蠢,果然看了大佬的代碼茅塞頓開。
代碼:
bool Find(int target,vector<vector<int> > array){
if(array.empty() || array[0].empty()) return false;
int len1 = array.size();
int len2 = array[0].size();
for(int i = 0; i < len1; i++){
if(target < array[i].front() || target > array[i].back()) continue;
for(int j = 0; j < len2; j++){
if(target == array[i][j]) return true;
}
}
return false;
}
改進:
定義row和col指向變量,row指向第一行,col指向最後一列,也就是我們選擇的初始比對位置在整個數組的右上角,初始位置這樣選擇我們一會就能看到這樣選擇的好處。
1 | 5 | 8 | 10 | 15 |
2 | 7 | 9 | 11 | 22 |
4 | 10 | 20 | 30 | 40 |
假設我們要查找的數字爲7
1 | 5 | 8 | 10 | 15 |
2 | 7 | 9 | 11 | 22 |
4 | 10 | 20 | 30 | 40 |
7<15,顯然15這一列的元素全都大於15,那麼這一列的元素也全都大於4,這一列可以全部排除,將col前移一位
1 | 5 | 8 | 10 | 15 |
2 | 7 | 9 | 11 | 22 |
4 | 10 | 20 | 30 | 40 |
7<10,繼續將col前移
1 | 5 | 8 | 10 | 15 |
2 | 7 | 9 | 11 | 22 |
4 | 10 | 20 | 30 | 40 |
7<8:
1 | 5 | 8 | 10 | 15 |
2 | 7 | 9 | 11 | 22 |
4 | 10 | 20 | 30 | 40 |
再次比對我們發現7>5,因爲本行中前面的元素都比5小,所以可以將本行的元素全部排除,row下移,到下一行尋找目標值:
1 | 5 | 8 | 10 | 15 |
2 | 7 | 9 | 11 | 22 |
4 | 10 | 20 | 30 | 40 |
7 == 7,成功找到了這個值!
這種方法,每一次比對都能排除一整行或者一整列的數據,大大節約了時間。
代碼:
if(array.empty() || array[0].empty()) return false;
int row = 0;
int col = array[0].size() - 1;
int rowLen = array.size();
while(col >= 0 && row < rowLen){
if(array[row][col] == target) return true;
else if(target > array[row][col]) row++;
else col--;
}
return false;