面試題3-二維數組中的查找
阿新 • • 發佈:2018-02-02
ams margin relative any eee bae int pla splay
面試題3-二維數組中的查找
劍指Offer基礎知識
數組是最簡單的一種數據結構,它占據一塊連續的內存並按照順序存儲數據。在創建數組的時候,必須首先指定數組的容量大小,然後根據大小來分配內存,一經建立之後數組的大小便不能更改,這就造成了其空間利用的效率不夠高。但是數組的內存是連續的,可以根據下標在O(1)的時間內讀寫任意的元素,因此它的時間效率很高。
在不同的編程語言中,都存在動態數組,如C++中的Vector,Java中的ArrayList。這些動態數組都有初始容量,當數據的數目超過數組的初始容量的時候,重新分配一塊更大的空間,把之前的數據復制到新的數組中去,釋放之前的內存,這樣減少了內存的浪費。但是每一次的擴容都會有大量的額外操作,這會對時間性能造成影響,因此在使用動態數組的時候要盡量減少改變數組容量的次數。
題目
在一個二維數組中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成提個函數輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。
解題思路:
- 這道題暴力的解法是兩層的循環逐一的查找,顯然這種復雜度O(mn)的算法是不可取的。
- 可以在此基礎之上進行改進,每一行使用二分查找的方法,減少查找的次數,那麽復雜度就能下降到O(mlgn)。
- 首先比較二維數組右上角的數字,若和目標數據相等,查找結束,如果該數字大於要查找的數字,則剔除這個數字所在的列;如果該數字小於要查找的數字,則剔除該數字所在的行。這樣一行一列的逐步縮小要查找的範圍,最後找到數字或者範圍為空。(仔細想想這種解法有點動歸的意思)這種思想的算法復雜度最壞情況下為O(m+n)。算法還是很神奇的。
代碼
二分:
- public class Solution {
- public boolean Find(int target, int [][] array) {
- if( array == null)
- return false;
-
- int row = array.length;
- //System.out.println(row);
- int col = array[0].length;
- boolean res = false;
- if(row > 0
- int min = array[0][0];
- int max = array[row-1][col-1];
- if(target < min || target > max)
- return false;
- //System.out.println("test");
- int i = 0;
-
- while( i < col){
- int low = 0,high = row - 1, mid = 0;
- while(low <= high){
- mid = low + (high - low)/2;
- if(target == array[i][mid]){
- res = true;
- return res;
- }
- if(target > array[i][mid]){
- low = mid + 1;
- }else{
- high = mid - 1;
- }
- }
- i ++;
- }
- }
- return res;
-
- }
- }
從右上刪減行列減少範圍:
- public class Solution {
- public boolean Find(int target, int [][] array) {
- int row = array.length;
- if(row == 0)
- return false;
- int col = array[0].length;
- int i = 0, j = col - 1;
- while(i < row && j >=0 ){
- if(target == array[i][j])
- return true;
- if(target > array[i][j])
- i++;
- else
- j--;
- }
- return false;
- }
- }
面試題3-二維數組中的查找