二分查找要注意边界值的取值,边界情况的判定

题目描述

编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:

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

示例 1:

输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3

输出:true

示例 2:

输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13

输出:false

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 100
  • -104 <= matrix[i][j], target <= 104

解答

解法一 先搜索在哪一行再搜索某一行

算法复杂度\(O(m+n)\)

class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int len = matrix.length;
int n = matrix[0].length;
for (int i = 0; i < len ; ++i) {
if (target >= matrix[i][0] && i + 1 <= len - 1 && target < matrix[i+1][0]) {
for (int j = 0; j < n; ++j) {
if (matrix[i][j] == target) {
return true;
}
}
}
else if (target >= matrix[i][0] && i == len - 1) {
for (int j = 0; j < n; ++j) {
if (matrix[i][j] == target) {
return true;
}
}
}
}
return false;
}
}

解法二 在解法一的基础上二分查找

算法复杂度\(O(log(mn))\)

class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length;
int n = matrix[0].length;
int m1 = findm(matrix, target, 0, m-1);
if (m1==-1) {return false;}
return findn(matrix[m1], target, 0, n-1);
}
public int findm(int[][] matrix, int target, int s, int t) { if (s == t) {
return target >= matrix[s][0] && target <= matrix[s][matrix[0].length-1] ? s : -1;
}
int mid = (s + t) >> 1;
if (target >= matrix[mid][0] && target < matrix[mid+1][0]) {
return mid;
}
else if (target > matrix[mid][0]) {
// 这里选择 mid+1 是为什么,细品一下
return findm(matrix, target, mid + 1, t);
}
else {
// 这里选择 mid 为什么不是 mid-1,继续品
return findm(matrix, target, s, mid);
}
}
public boolean findn(int[] matrix, int target, int s, int t) { if (s == t) {
return matrix[s] == target || matrix[t] == target;
}
int mid = (s + t) >> 1;
if (target == matrix[mid]) {
return true;
}
else if (matrix[mid] < target) {
return findn(matrix, target, mid + 1, t);
}
else {
return findn(matrix, target, s, mid);
}
}
}

解法三 将二维数组当做一维数组,二分查找

算法复杂度为\(O(log(m+n))\)

class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length;
int n = matrix[0].length; int pi = 0, pj = m * n - 1; while (pj > pi) {
int mid = (pi + pj) >> 1;
int i = mid / n;
int j = mid % n; if (matrix[i][j] == target) {
return true;
}
else if (matrix[i][j] > target) {
pj = mid;
continue;
}
else {
pi = mid + 1;
continue;
}
}
if (pi == pj) {
int i = pi / n;
int j = pi % n;
return matrix[i][j] == target;
}
return false;
}
}

leetcode 刷题(数组篇)74 题 搜索二维矩阵 (二分查找)的更多相关文章

  1. LeetCode:搜索二维矩阵【74】

    LeetCode:搜索二维矩阵[74] 题目描述 编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值.该矩阵具有如下特性: 每行中的整数从左到右按升序排列. 每行的第一个整数大于前一行的 ...

  2. LeetCode 74. 搜索二维矩阵(Search a 2D Matrix)

    74. 搜索二维矩阵 74. Search a 2D Matrix 题目描述 编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值.该矩阵具有如下特性: 每行中的整数从左到右按升序排列. ...

  3. 【leetcode】74. 搜索二维矩阵

    题目链接:传送门 题目描述 编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值.该矩阵具有如下特性: 每行中的整数从左到右按升序排列. 每行的第一个整数大于前一行的最后一个整数. 示例  ...

  4. Java实现 LeetCode 74 搜索二维矩阵

    74. 搜索二维矩阵 编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值.该矩阵具有如下特性: 每行中的整数从左到右按升序排列. 每行的第一个整数大于前一行的最后一个整数. 示例 1: ...

  5. Leetcode之二分法专题-240. 搜索二维矩阵 II(Search a 2D Matrix II)

    Leetcode之二分法专题-240. 搜索二维矩阵 II(Search a 2D Matrix II) 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target.该矩阵 ...

  6. LeetCode 240. 搜索二维矩阵 II(Search a 2D Matrix II) 37

    240. 搜索二维矩阵 II 240. Search a 2D Matrix II 题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target.该矩阵具有以下特性 ...

  7. Leetcode 240.搜索二维矩阵II

    搜索二维矩阵II 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target.该矩阵具有以下特性: 每行的元素从左到右升序排列. 每列的元素从上到下升序排列. 示例: 现有 ...

  8. Java实现 LeetCode 240 搜索二维矩阵 II(二)

    240. 搜索二维矩阵 II 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target.该矩阵具有以下特性: 每行的元素从左到右升序排列. 每列的元素从上到下升序排列. ...

  9. LeetCode74.搜索二维矩阵

    74.搜索二维矩阵 描述 编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值.该矩阵具有如下特性: 每行中的整数从左到右按升序排列. 每行的第一个整数大于前一行的最后一个整数. 示例 示 ...

  10. lintcode:搜索二维矩阵II

    题目 搜索二维矩阵 II 写出一个高效的算法来搜索m×n矩阵中的值,返回这个值出现的次数. 这个矩阵具有以下特性: 每行中的整数从左到右是排序的. 每一列的整数从上到下是排序的. 在每一行或每一列中没 ...

随机推荐

  1. 如何通过NGK数字增益平台实现兑换算力

    最近币圈里有一个新项目NGK非常火热,很多朋友在经过了了解以后纷纷表示很看好这个项目,那么除了二级市场之外,是否还能有其他的方式可以更低成本地获得NGK代币呢? 答案是肯定的,NGK数字增益平台便是低 ...

  2. NGK:APP一站式挖矿高收益项目

    NGK是10月中旬刚上线的公链项目,采用手机挖矿形式.NGK数字增益平台,200美金即可入场,收益可观,分为静态和动态两种,投资算力收益超高.邀请好友挖矿还有额外的返佣. NGK立志为所有人创造无差别 ...

  3. Github Packages和Github Actions实践之CI/CD

    概述 Github在被微软收购后,不忘初心,且更大力度的造福开发者们,推出了免费私有仓库等大更新.近期又开放了packages和actions两个大招,经笔者试用后感觉这两个功能配合起来简直无敌. G ...

  4. idea添加汉化包之后出现的一些问题 解决方案

    先把原链接放在这:https://jingyan.baidu.com/article/fb48e8bef2bcb66e622e14d2.html 关掉idea之后,一定要记住是在压缩软件中打开,而不是 ...

  5. 重量级锁synchronized的优化----自旋锁、自适应自旋锁、锁消除、锁粗化

    synchronized是重量级锁,效率不高.但在jdk 1.6中对synchronize的实现进行了各种优化,使得它显得不是那么重了.jdk1.6对锁的实现引入了大量的优化,如自旋锁.自适应自旋锁. ...

  6. jenkins+docker+nginx+tomcat实现vue项目部署

    一.项目准备 1.新建一个vue的项目,确保能在浏览器正常访问.然后在项目的根目录下新建一个Dockerfile的文件,内容如下 FROM nginx COPY dist /usr/share/ngi ...

  7. Docker-compose封装mysql并初始化数据以及redis

    一.概述 现有一台服务器,需要部署mysql和redis.其中mysql容器,需要在第一次启动时,执行sql文件. redis保持空数据即可. 关于Docker-compose的安装,请参考连接: h ...

  8. 后端程序员之路 41、BlockingQueue

    BlockingQueue,阻塞队列,常用于实现生产者和消费者模型特点:1.队列为空时,取操作会等到队列有数据2.队列满时,存操作会等到队列可用 基于C++11的阻塞队列简单实现 - Cynric 的 ...

  9. 一次Ubuntu16.04 虚拟机挂起,ping不到网络引发的思考

    虚拟机挂起 无网络 情况复现 can@ubuntu:~$ ping www.baidu.com ping: unknown host www.baidu.com 挂起重开虚拟机,遇到无网络状态: 首先 ...

  10. go 动态数组 二维动态数组

    go使用动态数组还有点麻烦,比python麻烦一点,需要先定义. 动态数组申明 var dynaArr []string 动态数组添加成员 dynaArr = append(dynaArr, &quo ...