算法二刷复盘|LeetCode 34&74 二分查找双杀(区间边界 + 二维矩阵)

目录

[一、LeetCode 34:在排序数组中查找元素的第一个和最后一个位置](#一、LeetCode 34:在排序数组中查找元素的第一个和最后一个位置)

题目描述

核心思路:两次二分,分别锁定左右边界

[Java 完整实现](#Java 完整实现)

复杂度分析

[二、LeetCode 74:搜索二维矩阵](#二、LeetCode 74:搜索二维矩阵)

题目描述

核心思路:二维降维,直接二分

[Java 完整实现](#Java 完整实现)

复杂度分析

三、两道题的二分核心对比

四、二刷复盘感悟


二刷二分查找,把两道高频变形题放在一起复盘:一道是一维排序数组的区间边界查找 ,一道是二维有序矩阵的降维二分。都是面试常考的二分应用场景,吃透这两道,就能掌握二分的核心变形技巧。


一、LeetCode 34:在排序数组中查找元素的第一个和最后一个位置

题目描述

给定一个升序排列的整数数组 nums 和目标值 target,找出目标值在数组中的开始和结束位置;若不存在,返回 [-1, -1]。要求算法时间复杂度为 O (log n)。

核心思路:两次二分,分别锁定左右边界

普通二分只能找到任意一个等于 target 的位置,这道题的关键是边界控制

  1. 找左边界 :当 nums[mid] == target 时,继续向左收缩右边界,直到找到第一个等于 target 的位置;
  2. 找右边界 :当 nums[mid] == target 时,继续向右收缩左边界,直到找到最后一个等于 target 的位置;
  3. 特殊处理 :若左边界不存在(即 nums[left] != target),直接返回 [-1,-1]

Java 完整实现

java

运行

复制代码
class Solution {
    public int[] searchRange(int[] nums, int target) {
        int left = findLeftBound(nums, target);
        if (left == -1) {
            return new int[]{-1, -1};
        }
        int right = findRightBound(nums, target);
        return new int[]{left, right};
    }

    // 找左边界:第一个等于target的位置
    private int findLeftBound(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] < target) {
                left = mid + 1;
            } else if (nums[mid] > target) {
                right = mid - 1;
            } else {
                // 等于target时,继续往左找,收缩右边界
                right = mid - 1;
            }
        }
        // 检查边界是否越界,且值是否匹配
        if (left < nums.length && nums[left] == target) {
            return left;
        }
        return -1;
    }

    // 找右边界:最后一个等于target的位置
    private int findRightBound(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] < target) {
                left = mid + 1;
            } else if (nums[mid] > target) {
                right = mid - 1;
            } else {
                // 等于target时,继续往右找,收缩左边界
                left = mid + 1;
            }
        }
        // 检查边界是否越界,且值是否匹配
        if (right >= 0 && nums[right] == target) {
            return right;
        }
        return -1;
    }
}

复杂度分析

  • 时间复杂度:O (log n),两次二分查找,整体仍为对数级复杂度;
  • 空间复杂度:O (1),原地操作,无额外空间开销。

二、LeetCode 74:搜索二维矩阵

题目描述

编写高效算法判断 m x n 矩阵中是否存在目标值。矩阵特性:

  • 每行从左到右升序排列;
  • 每行第一个整数大于前一行的最后一个整数。

核心思路:二维降维,直接二分

这道题的矩阵是严格有序 的,将矩阵按行拼接后就是一个一维升序数组,因此可以直接用普通二分解决,关键是一维索引与二维坐标的转换

  • 一维索引 mid 对应的二维行号:row = mid / nn 为矩阵列数);
  • 一维索引 mid 对应的二维列号:col = mid % n

Java 完整实现

java

运行

复制代码
class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        // 边界处理:空矩阵/空行/空列
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return false;
        }
        int m = matrix.length;
        int n = matrix[0].length;
        int left = 0;
        int right = m * n - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            // 转换为二维坐标
            int row = mid / n;
            int col = mid % n;
            if (matrix[row][col] == target) {
                return true;
            } else if (matrix[row][col] < target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return false;
    }
}

复杂度分析

  • 时间复杂度:O (log (m*n)),与普通二分一致,复杂度为对数级;
  • 空间复杂度:O (1),原地操作,无额外空间开销。

三、两道题的二分核心对比

表格

题目 核心考点 关键技巧 面试高频问题
34. 区间边界查找 二分的边界变形 两次二分,区分左右边界的收缩方向 如何处理 target 不存在的情况?左右边界的二分模板怎么写?
74. 二维矩阵搜索 二分的降维应用 二维坐标与一维索引的转换 若矩阵不严格有序(如 "Z" 字形有序),还能用这种方法吗?

四、二刷复盘感悟

  1. 二分的核心是「边界控制」 :34 题最容易出错的就是边界处理,尤其是等于 target 时的收缩方向,以及循环结束后的边界检查。统一使用「左闭右闭」模板,能大幅降低出错概率;
  2. 二分的本质是「有序数据的快速定位」:只要数据是有序的,不管是一维还是二维,都可以用二分优化。74 题就是典型的将二维有序转化为一维有序,再用二分解决;
  3. 面试常考变形拓展:除了这两道,「旋转排序数组的二分」「山脉数组的二分」也是高频考点,掌握通用模板就能举一反三
相关推荐
无敌昊哥战神1 小时前
【LeetCode 491】递增子序列:不能排序怎么去重?一文讲透“树层去重”魔法!
c语言·c++·python·算法·leetcode
TSINGSEE1 小时前
零代码自动化AI算法训练革命:企业级私有化部署DLTM自动化AI训练服务器,告别算法依赖
人工智能·深度学习·算法·机器学习·自动化·ai大模型
啊我不会诶2 小时前
【图论】基环树
算法·深度优先·图论
德卡先生的信箱2 小时前
算法部署(一)-模型压缩,剪枝,蒸馏的区别
算法·剪枝
WolfGang0073212 小时前
代码随想录算法训练营 Day44 | 图论 part02
算法·图论
minji...2 小时前
Linux 网络套接字编程(三)UDP服务器与客户端实现:Windows与Linux通信,新增字典翻译功能的 UDP 通信
linux·服务器·开发语言·网络·windows·算法·udp
Robot_Nav2 小时前
Hybrid A* 算法文献解读
算法·路径规划·hybrid a
WolfGang0073212 小时前
代码随想录算法训练营 Day41 | 单调栈 part01
算法·动态规划
嘻嘻哈哈樱桃2 小时前
牛客经典101题解题集--二分查找/排序
数据结构·算法·职场和发展