当前位置: 首页 > news >正文

LeetCode 热题 100 之 35. 搜索插入位置 74. 搜索二维矩阵 34. 在排序数组中查找元素的第一个和最后一个位置

本次道题目

35. 搜索插入位置

74. 搜索二维矩阵

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



35. 搜索插入位置

class Solution { public int searchInsert(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) { return mid; } else if (nums[mid] < target) { left = mid + 1; } else { right = mid - 1; } } // 循环结束时 left 就是插入位置 return left; } }
解题思路: 二分查找

初始化left = 0right = nums.length - 1(闭区间)。

循环条件:left <= right

  • 计算mid = left + (right - left) / 2(避免溢出)。

  • nums[mid] == target:直接返回mid

  • nums[mid] < target:目标在右侧,left = mid + 1

  • nums[mid] > target:目标在左侧,right = mid - 1

循环结束时,left就是目标值应插入的位置(此时left > rightleft指向第一个大于 target 的位置)。

为什么会溢出?

在 Java 中,int类型的取值范围是[-2^31, 2^31 - 1](即-2147483648 ~ 2147483647)。

  • 直接计算(left + right) / 2:如果leftright都是接近2^31 - 1的大数(比如left = 2147483640right = 2147483647),left + right会超出int的最大值,触发整数溢出,结果变成负数(比如2147483640 + 2147483647 = 4294967287,超出2^31 - 1,实际存储为-2147483641),导致mid计算错误。

  • 计算left + (right - left) / 2right - left是两个大数的差值,结果远小于2^31 - 1,不会溢出;再加上left,最终结果和(left + right) / 2等价,但完全避免了溢出风险。

74. 搜索二维矩阵

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; } }
class Solution { public boolean searchMatrix(int[][] matrix, int target) { int m = matrix.length, n = matrix[0].length; int low = 0, high = m * n - 1; while (low <= high) { int mid = (high - low) / 2 + low; int x = matrix[mid / n][mid % n]; if (x < target) { low = mid + 1; } else if (x > target) { high = mid - 1; } else { return true; } } return false; } } 作者:力扣官方题解 链接:https://leetcode.cn/problems/search-a-2d-matrix/solutions/688117/sou-suo-er-wei-ju-zhen-by-leetcode-solut-vxui/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
解题思路1:一次二分查找

把二维矩阵matrix[m][n]映射成一维数组:

  • 一维索引idx对应二维坐标:

    • 行号row = idx // n

    • 列号col = idx % n

  • 初始左指针left = 0,右指针right = m * n - 1

  • 每次取中间值mid = (left + right) // 2,转换为二维坐标后和target比较:

    • matrix[row][col] == target→ 找到,返回true

    • matrix[row][col] < target→ 目标在右侧,left = mid + 1

    • matrix[row][col] > target→ 目标在左侧,right = mid - 1

  • 循环结束仍未找到 → 返回false

class Solution { public boolean searchMatrix(int[][] matrix, int target) { int rowIndex = binarySearchFirstColumn(matrix, target); if (rowIndex < 0) { return false; } return binarySearchRow(matrix[rowIndex], target); } public int binarySearchFirstColumn(int[][] matrix, int target) { int low = -1, high = matrix.length - 1; while (low < high) { int mid = (high - low + 1) / 2 + low; if (matrix[mid][0] <= target) { low = mid; } else { high = mid - 1; } } return low; } public boolean binarySearchRow(int[] row, int target) { int low = 0, high = row.length - 1; while (low <= high) { int mid = (high - low) / 2 + low; if (row[mid] == target) { return true; } else if (row[mid] > target) { high = mid - 1; } else { low = mid + 1; } } return false; } } 作者:力扣官方题解 链接:https://leetcode.cn/problems/search-a-2d-matrix/solutions/688117/sou-suo-er-wei-ju-zhen-by-leetcode-solut-vxui/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
解题思路2:两次二分查找

由于每行的第一个元素大于前一行的最后一个元素,且每行元素是升序的,所以每行的第一个元素大于前一行的第一个元素,因此矩阵第一列的元素是升序的。

我们可以对矩阵的第一列的元素二分查找,找到最后一个不大于目标值的元素,然后在该元素所在行中二分查找目标值是否存在。

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

非递减有序数组(也叫 “非严格递增数组”)是指:数组中每个元素都大于或等于它前面的元素(nums[i] ≥ nums[i-1]i > 0)。

class Solution { public int[] searchRange(int[] nums, int target) { int left = findLeft(nums, target); int right = findRight(nums, target); // 不存在的情况 if (left == nums.length || nums[left] != target) { return new int[]{-1, -1}; } return new int[]{left, right}; } // 找左边界:第一个 >= target 的位置 private int findLeft(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) { right = mid - 1; } else { left = mid + 1; } } return left; } // 找右边界:最后一个 <= target 的位置(比基于找到左边界再遍历快一点数据大的话) private int findRight(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 { right = mid - 1; } } return right; } }
解题思路:两次二分查找

找左边界

  • 初始化left = 0,right = len(nums) - 1

  • 循环条件:left <= right

  • nums[mid] >= target时,说明左边界在左半部分,令right = mid - 1

  • nums[mid] < target时,说明左边界在右半部分,令left = mid + 1

  • 循环结束后,left即为第一个 ≥ target 的位置,若left越界或nums[left] != target,则不存在

找右边界

  • 初始化left = 0,right = len(nums) - 1

  • 循环条件:left <= right

  • nums[mid] <= target时,说明右边界在右半部分,令left = mid + 1

  • nums[mid] > target时,说明右边界在左半部分,令right = mid - 1

  • 循环结束后,right即为最后一个 ≤ target 的位置,若right越界或nums[right] != target,则不存在

http://www.cnnetsun.cn/news/1367872.html

相关文章:

  • SiamMask核心原理深度解析:孪生网络如何统一跟踪与分割
  • 5分钟搞定!用MediaMTX和FFmpeg搭建RTSP转HLS直播流(含低延迟配置)
  • [技术突破]48Tools直播数据采集系统:从故障修复到架构升级的实践之路
  • **标题:MLOps实战进阶:基于Docker+Kubernetes的
  • ContextCapture Center 在智慧城市建设中的实景三维建模实践
  • 探索Java世界的新表情——emoji-java库
  • 认真写的论文被当AI?百考通:降重+降AI,为原创者正名!
  • 如何使用vscode-markdown-pdf:3分钟快速上手指南
  • 【亲测免费】 推荐一款强大的开源网址导航系统:WebStack-Laravel
  • 从像素到对象:手把手教你理解Cutie的遮蔽注意力机制(附代码解读)
  • 三维重建质量评估:从像素到感知的四大核心指标解析
  • 某盾blackBox逆向避坑指南:如何应对频繁更新的JS混淆策略
  • SQL Server数据库被标记为SUSPECT?5步紧急修复指南(附完整命令)
  • freeRTOS任务通知 vs 队列:ESP32场景下5种通信方式性能实测
  • Deepagents环境价值:构建智能AI代理的完整生态系统指南
  • HalfCheetah-v2 环境下的深度强化学习算法实现分析
  • 保姆级教程:在Ubuntu 22.04上给ROS2 Humble的USB摄像头做内参标定(附结果文件解读)
  • WebGAL高级特效开发:如何利用滤镜和变换创造独特视觉风格
  • 重构Ozon流量运营逻辑,Captain AI解锁跨境增长新范式
  • 3大核心功能革新性重塑Discord机器人管理体验:开发者与运营者的一站式控制台
  • PAT-Hashing (25)
  • Hunyuan-MT-7B实战:如何用Chainlit前端快速调用翻译服务
  • 探索未来3D建模的新可能:Blackjack——轻量级的程序化建模工具
  • OpenSpeedy:重新定义游戏时间流速的技术突破
  • CSVtoTable错误排除指南:解决常见问题的7个有效方法
  • Ansys Comsol 力磁耦合仿真,包括直接耦合与间接耦合方式,模拟金属磁记忆检测以及压磁...
  • 《认知准晶体的五重对称性验证:人类创造性思维与AI生成内容的结构对比》(沙地实验)
  • DeepSeek-OCR-2企业级OCR方案:支持批量上传+API调用部署教程
  • AWS Lambda Rust运行时的高级特性:流式响应、并发处理与优雅关闭
  • Apache NuttX社区贡献指南:如何参与开源实时操作系统开发