劍指offer-在二維數組中查找

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

示例:

現有矩陣 matrix 如下:

[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
給定 target = 5,返回 true。

給定 target = 20,返回 false。

限制:

0 <= n <= 1000

0 <= m <= 1000

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof

解析:
方案1: 二叉搜索法!
由題目可以知道,對於右上角的元素,其左邊列的元素必定比它小,其下面行的元素必定比它大,所以從右上角開始搜索,遇到比target大的元素,則往左邊列搜索,遇到比target小的元素,則往下一行搜索,如果搜索到左下角,還沒有搜索到,則是不存在target元素


func findNumberIn2DArray(matrix [][]int, target int) bool {
	if matrix==nil || len(matrix)==0{
		return false
	}
	indexI:=0
	indexJ:=len(matrix[indexI])-1
	if indexJ==-1{
		return false
	}
	for {

		if indexI>=len(matrix) || indexJ<0{
			return false
		}
		//fmt.Println("當前查找值:",matrix[indexI][indexJ])

		if indexI==len(matrix)-1 && indexJ==0 && matrix[indexI][indexJ]!=target{
			return false
		}
		if matrix[indexI][indexJ]==target{
			return true
		}else if matrix[indexI][indexJ]>target{
			indexJ-=1

		}else if matrix[indexI][indexJ]<target{
			indexI+=1

		}
	}
}

方案二:兩次二分查找,先二分找到是哪些行可能存在target,再遍歷這麼行,對每行進行二分,查找可能是這一行的那一列

func findNumberIn2DArray(matrix [][]int, target int) bool {
	if len(matrix)==0 || matrix==nil{
		return false
	}
	var nums []int
	for i := 0; i < len(matrix); i++ {
		if len(matrix[i])!=0{ // 數組裏面有東西才加入
			nums = append(nums, matrix[i][0])
		}
	}
	indexI := sort.Search(len(nums), func(i int) bool {
		return nums[i] >= target
	})
	//fmt.Println("indexI: ",indexI)
	//fmt.Println("nums:",nums)

	if indexI==len(nums){ // 沒找到>=target的第一個數字
		indexI-=1
	}

	// 找到了>=target的第一個數字
	for i:=indexI;i>=0;i--{

		indexJ:=sort.Search(len(matrix[i]), func(j int) bool {
			return matrix[i][j]>=target
		})

		for j:=indexJ;j<len(matrix[i]);j++{
			if matrix[i][j]==target{
				return true
			}
		}
	}
	return false
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章