LeetCode240 搜索二维矩阵 II

76 阅读2分钟

leetcode.cn/problems/se…

前言

先来看看这题的基础版 ,显然是二分查找的思路。 image.png 一维数组上的二分查找框架

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
}

回到本题解析

image.png 这道题不算二分搜索算法,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
}