二維“有序”數組查找問題的解決


題目:在一個二維數組中,每一行都按照從左到右遞增的順序排序,誒一列都按照從上到下遞增的順序排序,請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否包含了該整數。
 
        例如下面的二維數組就是每行、沒列都遞增排序。如果在這個數組中查找數字7,則返回true(找得到);如果查找數字5,由於數組不含該數字,則返回false。
1 2 8 9
2 4 9 12
4 7 10 13
6 8 11 15
        如下圖所示,會出現 三種情況
  1. 數組中選取的數字(圖中全黑的位置)剛好是要查找的數字(相等),查找過程結束;
  2. 選取的數字小於要查找的數字,那么根據數組排序的規則,要查找的數字應該在當前位置的右邊或者下邊(如下圖2.1(a)所示)
  3. 選取的數字大於要查找的數字,那么要查找的數字應該在當前選取的位置的上邊或者左邊。

 

分析:
       由上圖可知,當不等於要查找的數字的時候會出現兩片要查找的區域重疊的情況。我們該怎么考慮呢?                 
        我們可以 從數組的一個角上選取數字來和要查找的數字做比較,情況會變得簡單一些。如:首先選取數組右上角的數字9。 由於9大於7,並且還是第4列的第一個(也是最小的)的數字,因此7不可能出現在數字9所在的列。於是我們 把這一從需要考慮的區域內剔除,之后只需分析剩下的3列(如下圖(a)所示)。在剩下的矩陣中,位於右上角的數字是8,同樣 8大於7,因此 8所在的我們也可以剔除。接下來我們只要分析剩下的兩列即可(如下圖(b) 所示)。
        在由剩下的兩列組成的數組中,數字2位於數字的右上角。 2小於7,那么要查找的7可能在2的右邊,也有可能在2的下邊。在前面的步驟中,我們已經發現2右邊的列都已經被剔除了每頁就是說7不可能出現在2的右邊,因此7只有可能出現在2的下邊。於是我們 把數字2所在的也剔除,值分析剩下的三行兩列數組(如下圖(c)所示)。在剩下的數字中4位於右上角,和前面一樣,我們把數字 4所在的也剔除,最后剩下兩行兩列數字(如圖(d)所示)
        在剩下的兩行兩列4個數字中, 位於右上角的剛好就是我們要查找的數字7,於是 查找過程就可以 結束了。
 
1 2 8 9
2 4 9 12
4 7 10 13
6 8 11 15
(a)
1 2 8 9
2 4 9 12
4 7 10 13
6 8 11 15
(b)
1 2 8 9
2 4 9 12
4 7 10 13
6 8 11 15
(c)
1 2 8 9
2 4 9 12
4 7 10 13
6 8 11 15
(d)
    注:矩陣中加顏色的的區域是下一步查找的范圍。
 
總結
        總結上述查找的過程,我們發現如下規律:首先選取數組中右上角的數字。如果該數字 等於要查找的數字, 查找過程 結束;如果該數字 大於要查找的數字, 剔除這個數字所在 ;如果該數字 小於要查找的數字, 剔除這個數字所在的
 

編碼實現
核心算法:
 /**
  * 
  * @param num 被查找的二維數組
  * @param rows 行數
  * @param columns 列數
  * @param number 要查找的數字
  * @return 是否找到要查找的數字(number)
  */
 public static Boolean Find(int num[][],int rows,int columns,int number)
 {
  Boolean found = false;
  int row = 0;
  int column = columns - 1 ;
  
  if( rows > 0 && columns >0)
  {
   while(row < rows && column >= 0)
   {
    if(num[row][column] == number)  //查找到
    {
     found = true;
     break;
    }
    else if(num[row][column] >number)
    {
     --column;  //刪除列
    }
    else
    {
     ++row;  //刪除行
    }
     
   }
  }
  return found;
 }

 

 

 測試:

 

public static void main(String[] args)
 {
  //初始化數字的值
  int num[][]= {{1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15}};
  
  System.out.println(Find(num,4,4,7)); //在數組中
  
  System.out.println(Find(num,4,4,5)); //5不在數組中
 }

 

 

 結果:

true
false

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM