前言
先来看看这题的基础版
,显然是二分查找的思路。
一维数组上的二分查找框架
func binarySearch(nums []int, target int) int {
left, right := 0, len(nums)-1
for left <= right{
mid := left + (right-left)/2
if nums[mid] == target{
return mid
}else if nums[mid] > target{
right = mid-1
}else if nums[mid] < target{
left = mid+1
}
}
return -1
}
题意说的这种有序二维数组,是可以映射为一维数组查询的,框架一模一样
只要知道二维数组的的行数 m 和列数 n,二维数组的坐标 (i, j) 可以映射成一维的 index = i * n + j;反过来也可以通过一维 index 反解出二维坐标 i = index / n, j = index % n。
二维矩阵的二分查找题解
func searchMatrix(matrix [][]int, target int) bool {
// 将二维数组 “展平” 成一维有序数组,然后进行标准的二分搜索
rows ,cols := len(matrix) ,len(matrix[0])
left, right := 0, rows*cols-1
for left <= right{
mid := left + (right-left)/2
// 将一维索引反解出二维坐标
r := mid/cols
c := mid%cols
if matrix[r][c] == target{
return true
}else if matrix[r][c] > target{
right = mid-1
}else if matrix[r][c] < target{
left = mid+1
}
}
return false
}
回到本题解析
这道题不算二分搜索算法,
matrix 从上到下递增,从左到右递增,显然左上角是最小元素,右下角是最大元素。我们如果想高效在 matrix 中搜索一个元素,肯定需要从某个角开始,比如说从左上角开始,然后每次只能向右或向下移动,不要走回头路。如果真从左上角开始的话,就会发现无论向右还是向下走,元素大小都会增加,那么到底向右还是向下?不确定
我们不要从左上角开始,而是从右上角开始,规定只能向左或向下移动。如果向左移动,元素在减小,如果向下移动,元素在增大,这样的话我们就可以根据当前位置的元素和 target 的相对大小来判断应该往哪移动,不断接近从而找到 target 的位置。
func searchMatrix(matrix [][]int, target int) bool {
rows, cols := len(matrix), len(matrix[0])
r, c := 0, cols-1 // 初始位置在矩阵右上角
for r < rows && c >= 0{
if matrix[r][c] == target {
return true
}else if matrix[r][c] < target{ // 向下移动,寻找更大的数
r++
}else{ // 向左移动,寻找更小的数
c--
}
}
return false
}