【LeetCode】74. 搜索二维矩阵

leetcode

 

解题思路

该问题要求在一个满足​​行列双重有序​​的矩阵中高效查找目标值:

  1. ​​行列有序特性​​
    • 每行元素从左到右​​非严格递增​​(允许重复值)
    • 每行首元素 > 上一行末元素(整体连续递增)
  2. ​​核心思想​​:
    • 将二维矩阵视为​​一维有序数组​​(满足条件2保证全局有序)
    • 通过​​二分查找​​直接定位目标值
  3. ​​关键转换​​:
    • 一维索引 idx → 二维坐标 (row, col)
      • row = idx / 列数
      • col = idx % 列数

此方法时间复杂度为 O(log(mn)),优于行列分别查找的 O(mlogn)

关键步骤

  1. ​​边界处理​​:
    • 空矩阵直接返回 false
    • 单元素矩阵直接比较
  2. ​​二分查找初始化​​:
    • 左指针 left = 0
    • 右指针 right = 行数×列数 - 1
  3. ​​索引转换​​:
    • 计算中点 mid = (left + right) / 2
    • 行列坐标:row = mid / ncol = mid % nn为列数)
  4. ​​比较更新​​:
    • matrix[row][col] == target → 返回 true
    • matrix[row][col] < target → left = mid + 1
    • matrix[row][col] > target → right = mid - 1

代码实现

func searchMatrix(matrix [][]int, target int) bool {
    // 空矩阵检查
    if len(matrix) == 0 || len(matrix[0]) == 0 {
        return false
    }

    rows, cols := len(matrix), len(matrix[0])
    left, right := 0, rows*cols-1 // 初始化一维索引边界

    for left <= right {
        mid := left + (right-left)/2 // 防溢出计算中点
        row := mid / cols            // 行索引 = 一维索引/列数
        col := mid % cols            // 列索引 = 一维索引%列数

        if matrix[row][col] == target {
            return true
        } else if matrix[row][col] < target {
            left = mid + 1 // 目标在右半区
        } else {
            right = mid - 1 // 目标在左半区
        }
    }

    return false
}

示例测试

func main() {
    // 示例1:存在目标值
    matrix1 := [][]int{
        {1, 3, 5, 7},
        {10, 11, 16, 20},
        {23, 30, 34, 60},
    }
    fmt.Println(searchMatrix(matrix1, 3)) // true

    // 示例2:不存在目标值
    fmt.Println(searchMatrix(matrix1, 13)) // false

    // 单行矩阵
    matrix2 := [][]int{{1, 3, 5, 7}}
    fmt.Println(searchMatrix(matrix2, 5)) // true
    fmt.Println(searchMatrix(matrix2, 2)) // false

    // 单元素矩阵
    matrix3 := [][]int{{5}}
    fmt.Println(searchMatrix(matrix3, 5)) // true
    fmt.Println(searchMatrix(matrix3, 0)) // false

    // 包含重复值
    matrix4 := [][]int{
        {1, 3, 5, 7},
        {7, 8, 9, 10},
    }
    fmt.Println(searchMatrix(matrix4, 7)) // true
}

复杂度分析

​​指标​​​​值​​​​说明​​
​​时间复杂度​​ O(log(mn)) 二分查找的迭代次数
​​空间复杂度​​ O(1) 仅需常数级变量存储指针
​​优势场景​​ 大规模矩阵 100万元素只需约20次比较

关键点总结

  1. ​​全局有序证明​​:

    • 条件2(每行首元素 > 上一行末元素)确保矩阵整体有序
    • 示例:[1,3,5,7] → [10,...] → [23,...] 形成连续序列 1,3,5,7,10,11,...
  2. ​​索引转换原理​​:

    • 列数 n 作为转换基准:
      row = idx / n  // 整数除法自动向下取整
      col = idx % n  // 取余获得列偏移
  3. ​​二分查找变体​​:

    • 标准二分查找在一维数组的扩展应用
    • 比较时直接使用二维数组元素值
  4. ​​边界处理细节​​:

    • ​​空矩阵检查​​:避免 cols=0 导致的除零错误
    • ​​单元素优化​​:逻辑已涵盖,无需特殊处理
posted @ 2025-06-19 11:16  云隙之间  阅读(27)  评论(0)    收藏  举报