算法练习题18——leetcode240搜索二维矩阵||(二分)

题目描述

编写一个高效的算法来搜索 m xn 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:

每行的元素从左到右升序排列。

每列的元素从上到下升序排列。

代码

复制代码
class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        for(int[] row:matrix){
            int index = search(row,target);
            if(index>=0){
                return true;
            }
        }
        return false;
    }
    public int search(int[] nums, int target) {
        int low = 0, high = nums.length - 1; // 初始化指针
        while (low <= high) {
            int mid = (high - low) / 2 + low; // 计算中点,防止整数溢出
            int num = nums[mid]; // 获取中点值
            if (num == target) { // 找到目标值
                return mid;
            } else if (num > target) { // 目标值在左半部分
                high = mid - 1;
            } else { // 目标值在右半部分
                low = mid + 1;
            }
        }    
    return -1; // 没有找到目标值
    }
}

复杂度分析

  • 时间复杂度:O(mlogn)。对一行使用二分查找的时间复杂度为 O(logn),最多需要进行 m 次二分查找。

  • 空间复杂度:O(1)。

示例和解释

假设我们有一个升序的数组 nums = [1, 3, 5, 7, 9, 11],目标值 target = 7。让我们看看这个算法如何找到目标值:

  1. 初始状态:

    • 数组:[1, 3, 5, 7, 9, 11]
    • low = 0,high = 5(数组的长度为 6,所以索引范围是 0 到 5)
  2. 第一次迭代:

    • 计算中点索引:mid = (high - low) / 2 + low = (5 - 0) / 2 + 0 = 2
    • 中点值:nums[mid] = nums[2] = 5
    • 比较:5 < 7(中点值小于目标值)
    • 更新指针:将 low 指针移动到 mid + 1 = 3,high 保持不变(5)
  3. 第二次迭代:

    • 新的范围:[7, 9, 11](索引 3 到 5)
    • 计算中点索引:mid = (high - low) / 2 + low = (5 - 3) / 2 + 3 = 4
    • 中点值:nums[mid] = nums[4] = 9
    • 比较:9 > 7(中点值大于目标值)
    • 更新指针:将 high 指针移动到 mid - 1 = 3,low 保持不变(3)
  4. 第三次迭代:

    • 新的范围:[7](索引 3 到 3)
    • 计算中点索引:mid = (high - low) / 2 + low = (3 - 3) / 2 + 3 = 3
    • 中点值:nums[mid] = nums[3] = 7
    • 比较:7 == 7(中点值等于目标值)
    • 找到目标值,返回 mid = 3

结果

目标值 7 在数组中的索引是 3,所以函数返回 3。

另一个示例

假设我们有同样的数组 nums = [1, 3, 5, 7, 9, 11],但目标值 target = 4,这个值不在数组中。我们看看算法如何工作:

  1. 初始状态:

    • 数组:[1, 3, 5, 7, 9, 11]
    • low = 0,high = 5
  2. 第一次迭代:

    • 计算中点索引:mid = (high - low) / 2 + low = (5 - 0) / 2 + 0 = 2
    • 中点值:nums[mid] = nums[2] = 5
    • 比较:5 > 4(中点值大于目标值)
    • 更新指针:将 high 指针移动到 mid - 1 = 1,low 保持不变(0)
  3. 第二次迭代:

    • 新的范围:[1, 3](索引 0 到 1)
    • 计算中点索引:mid = (high - low) / 2 + low = (1 - 0) / 2 + 0 = 0
    • 中点值:nums[mid] = nums[0] = 1
    • 比较:1 < 4(中点值小于目标值)
    • 更新指针:将 low 指针移动到 mid + 1 = 1,high 保持不变(1)
  4. 第三次迭代:

    • 新的范围:[3](索引 1 到 1)
    • 计算中点索引:mid = (high - low) / 2 + low = (1 - 1) / 2 + 1 = 1
    • 中点值:nums[mid] = nums[1] = 3
    • 比较:3 < 4(中点值小于目标值)
    • 更新指针:将 low 指针移动到 mid + 1 = 2
  5. 结束条件:

    • 现在 low = 2,high = 1,满足 low > high,循环结束。
    • 目标值 4 不在数组中,返回 -1。
相关推荐
silvamux_1 小时前
10款模型写种草笔记:可发布性、返工来源与成本数据缺口复盘
java·数据库·笔记
步行cgn2 小时前
StringHttpMessageConverter 详解:Spring MVC 中字符串读写的默认转换器
java·spring·mvc
摇滚侠2 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 11
java·笔记·python
小蒜学长2 小时前
基于Spring Boot+Vue3的在线医疗咨询系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·在线问诊·在线医疗咨询系统
Deng桑2 小时前
SpringAI写第一个Agent-把工单循环跑起来
java·agent·工具调用·spring ai
小蒋观天下2 小时前
雷击与浪涌防护:前端SPD选型、接地网误区,接地不当反而引入干扰
深度学习·算法·机器学习
lvwangshu2 小时前
P15569 [COCI 2025/2026 #5] 结构 / Struktura 题解
矩阵·题解·dp·推导题·矩阵加速
WBluuue4 小时前
数据结构与算法:分块(一):块状数组、块状链表
数据结构·c++·算法·链表
圣保罗的大教堂4 小时前
leetcode 3619. 总价值可以被 K 整除的岛屿数目 中等
leetcode