算法二刷复盘|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. 面试常考变形拓展:除了这两道,「旋转排序数组的二分」「山脉数组的二分」也是高频考点,掌握通用模板就能举一反三
相关推荐
Dlrb12118 小时前
C语言-指针数组与数组指针
c语言·数据结构·算法·指针·数组指针·指针数组·二级指针
WL_Aurora8 小时前
Python 算法基础篇之集合
python·算法
平行侠8 小时前
A15 工业路由器IP前缀高速检索与内存压缩系统
网络·tcp/ip·算法
阿旭超级学得完10 小时前
C++11包装器(function和bind)
java·开发语言·c++·算法·哈希算法·散列表
li星野10 小时前
位运算 & 数学 & 高频进阶九题通关(Python + C++)
c++·python·学习·算法
jerryinwuhan10 小时前
hello算法,简单讲(1)
算法·排序算法
y = xⁿ10 小时前
20天速通LeetCodeday15:BFS广度优先搜索
算法·宽度优先
400分10 小时前
吃透RAG核心-----语义检索与关键字检索底层原理
算法·架构
目黑live +wacyltd10 小时前
算法备案:常见驳回原因与应对策略
人工智能·算法
磊 子10 小时前
多态类原理+四种类型转换+异常处理
开发语言·c++·算法