数据结构与算法--数组:二维数组中查找
數(shù)組
- 數(shù)組最簡單的是數(shù)據(jù)結(jié)構(gòu),占據(jù)一整塊連續(xù)的內(nèi)存并按照順序存儲數(shù)據(jù),創(chuàng)建數(shù)組時候,我們需要首先指定數(shù)組的容量大小,然后根據(jù)大小分配內(nèi)存。即使我們只在數(shù)組中存儲一個元素,亞需要為所有數(shù)據(jù)預(yù)先分配內(nèi)存,因此空間使用效率差,經(jīng)常會有空閑區(qū)域沒有得到充分利用。
- 由于數(shù)組中內(nèi)存是連續(xù)的,于是可以根據(jù)下標(biāo)在O(1)時間內(nèi)讀/寫任何元素,因此時間效率很高。
- 為解決數(shù)組空間效率問題,人們設(shè)計實現(xiàn)了多種動態(tài)數(shù)組,Java中的vector。為了避免浪,我們先為數(shù)組開辟一個較小的空間,然后向數(shù)組添加元素的過程中,當(dāng)元素個數(shù)超過數(shù)組容量的時候,我們會重新分配一個更大的空間,接著吧之前的數(shù)據(jù)復(fù)制到新的駐足中,在將之前的內(nèi)存釋放,這樣就能減少內(nèi)存的浪費(fèi)。但是每一層擴(kuò)充數(shù)組容量都有大量的額外操作,這多時間性能有負(fù)面的影響,因此使用動態(tài)數(shù)組時候要盡量減少改變數(shù)組容量大小的次數(shù)。
算法題:二維數(shù)組中查找
- 題目:在一個二維數(shù)組中,每一行從左到右遞增順序存儲,每一列都按照從上到下遞增順序排序。完成一個函數(shù),輸入這樣一個二維數(shù)組和一個整數(shù),輸出數(shù)組中是否包含改整數(shù)以及改整數(shù)的位置。
- 分析過程如下: 例如下面二維數(shù)組,每行,列都遞增。如果這個數(shù)組中查找數(shù)字6,則返回true,位置(2,1)。如果查找數(shù)字5返回false
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
錯誤解法分析過程如下
- 按照題目要求,每列,行都遞增,如上,通過觀察以上矩陣的特性,很多同學(xué)會采用二分法,步驟如下:
- 將二維數(shù)組看成是一個現(xiàn)象的結(jié)構(gòu),總共有20個元素,left=0,right=20, mid= (left+right)/2=10
- 取中間位置元素值value與目標(biāo)元素key比較
- value == key 則得出結(jié)果
- value < key則left = mid + 1
- value > key 則right = mid - 1
- 具體實現(xiàn)如下
- 以下測試案例:
- 如上測試用例可知,以上解法是錯誤的,原因在于雖然此二維數(shù)組每一列每一行都遞增,當(dāng)并不代表中間元素mid之前的元素一定小于mid導(dǎo)致程序出錯。
正確解法分析過程如下
-
還是將二維數(shù)組看成矩陣,,從中選一個元素 m與目標(biāo)值key比較,分三種情況分析查找,
- 情況一 當(dāng) m == key,結(jié)束查找
- 情況二 當(dāng) m < key,根據(jù)數(shù)組排序規(guī)則,要查找的數(shù)字應(yīng)該在當(dāng)前選區(qū)的位置的右邊或者下面
- 情況三 當(dāng)m > key,同樣的,要查的數(shù)字應(yīng)該在左邊或者上面
-
如上分析,由于需要朝招的數(shù)字相對當(dāng)前選取的m的位置有可能兩個區(qū)域,而且有重疊,這樣看起來就復(fù)雜了。
-
我們將問題具體化,。下面以上圖中矩陣中查找數(shù)字7 為案例,一步步分析查找過程。
-
之前之所以困難,是我們在二維數(shù)組的中間選取的數(shù)字m 與目標(biāo)值key比較,這樣導(dǎo)致下一次需要查找的兩個相互重疊的區(qū)域。如果我們從數(shù)組的一個角上選取,情況如下:
-
首先選右上角數(shù)字9, 9 > 7,并且9 還在第四列的第一個數(shù)字,所有,7 不可能在第四列
-
將剩下三列看成一個新的二維數(shù)組,同樣選右上角 8 > 7 ,同樣可以排除第三列數(shù)
-
將剩下兩列看成一個新二維數(shù)組,同樣選右上角2 < 7,那么要查找的7 可能在2的右邊也可能在2 的下面,因為之前的操作已經(jīng)將右邊的所有數(shù)據(jù)都排除了,所有必定在2 的下面,并且將2 這一行踢出,只剩下3*2 的二維數(shù)組,如下
-
剩下上圖中,同樣用這個方法,去右上角4 < 7 ,所以不再這一行,可能在4下面,剩下2*2 的二維數(shù)組
-
-
接著在取右上角 7 = 7 得出最終答案。
總結(jié)
- 以上查找過程,有如下規(guī)律:首先選取數(shù)組中右上角元素,
- 如果改數(shù)字等于要查找數(shù)字,結(jié)束查找
- 如果改數(shù)字小于要查找數(shù)字,踢出這個數(shù)字所在行
- 如果這個數(shù)字大于要查找的數(shù)字,踢出這個數(shù)字所在的列
- 依次每一步都在查找范圍內(nèi)踢出一列或者一行,逐步縮小范圍。直到查詢到或者為空。
- 如下代碼實現(xiàn)。
- 時間復(fù)雜度 O(max(rows, cloumns)),空間復(fù)雜度 O(1)
- 測試用例:
- 二維數(shù)組中查找包含的數(shù)字,數(shù)組中最大值,最小值,介于最大最小之間的值
- 二維數(shù)組中查找不包含的數(shù)字,大于最大值,小于最小值,介于最大最小之前的不存在的值
- 特殊輸入 null
其他思路
- 以上是去右上角的數(shù)字,統(tǒng)一,可以選左下角的數(shù)字,
- 不能選左上角的數(shù)字,例如選擇1, 1 < 7 ,那么7 位于1 的下面或者右邊,沒有參考意義。
- 不能選右下角的數(shù)字,例如15 , 15 > 7,那么7 位于15 的上面或者左邊,沒有參考意義。
上一篇 數(shù)據(jù)結(jié)構(gòu)與算法–實現(xiàn)Singleton模式
下一篇:數(shù)據(jù)結(jié)構(gòu)與算法–字符串:字符串替換
總結(jié)
以上是生活随笔為你收集整理的数据结构与算法--数组:二维数组中查找的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 心气虚的症状有哪些
- 下一篇: 数据结构与算法--经典10大排序算法(动