有序二維數組查找元素的幾種方式

問題描述

在一個二維整數數組中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,
輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。

參數說明

int[][] array:二維數組
target:整數
存在返回true,否則返回false

暴力直接遍歷整個二維數組
不做解釋

public boolean Find1(int[][] array, int target) {

		for (int arraya[] : array) {
			for (int b : arraya) {
				if (target == b) {
					return true;
				}
			}
		}
		return false;

	}

二分法
對於有序的數組,二分法無疑是最優的算法。將每一行的元素使用二分法查找元素。

// 將每一行的元素進行二分查找
	public boolean Find2(int[][] array, int target) {

		for (int i = 0; i < array.length; i++) {
			int low = 0;
			int high = array[i].length - 1;
			while (low <= high) {
				int mid = (low + high) / 2;
				if (target > array[i][mid])
					low = mid + 1;
				else if (target < array[i][mid])
					high = mid - 1;
				else
					return true;
			}
		}
		return false;

	}

左下角元素開始遍歷
將每一列視爲整體,每一列中最大的元素爲最下面的一個。所以我們只需比較每一列的最大的元素,當小於這個元素時,向上用二分法查找這一列的元素。

// 從左下角開始遍歷,元素大於target時向上遍歷,小於則向右遍歷
	public boolean Find3(int[][] array, int target) {
		int len = array.length - 1;
		int i = 0;
		while ((len >= 0) && (i < array[0].length)) {
			if (array[len][i] > target) {
				len--;
			} else if (array[len][i] < target) {
				i++;
			} else {
				return true;
			}
		}
		return false;
	}

分模塊二分+遞歸查找
而且這樣的矩陣有個性質,最左上角的元素必定是最小值,最右下角的是最大值,在一個
nn的矩陣中,對角線的元素也是排好序的,找到對角線上的一個元素,使得這個元素小於
待查找的key,並且下一元素大於待查找的key,那麼只要在這個元素的左下角矩陣和右上角
矩陣遞歸繼續對角線查找就可以了,例如上圖例子裏查找7,只要找到對角線的元素4,然後
遞歸查找紅圈的矩陣就可以了,在這裏插入圖片描述左上角矩陣最大值4<7,右下角
矩陣最小值10>7,無需查找了,但是此題並沒有告訴我們原始矩陣是n
n的,這是比較麻煩的
地方,不過思路是一樣的,無非不能用對角線查找這樣簡單的辦法了,假設m*n的矩陣,對角線
查找的辦法改進爲i = (m1+m2)/2,j = (n1+n2)/2 進行查找就可以了,(m1,n1)爲矩陣最左上角
元素下標,(m2,n2)爲最右下角元素下標
在這裏插入圖片描述
假設查找17,第一次比較10,然後比較25,然後比較13,返回元素13,這時候再遞歸查找13
左下角的矩陣和右上角的矩陣就可以了(紅色橢圓部分);如果是查找9,第一次比較10,然後比較4,
然後比較6,返回元素6,這時候遞歸查找6左下角的矩陣和右上角矩陣(綠色橢圓部分)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章