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

leetcode 之 二分查找(java)(2)

文章目录

    • 74、搜索二维矩阵
    • 33、搜素旋转排序数组

74、搜索二维矩阵

题目描述

给你一个满足下述两条属性的 m x n 整数矩阵:

  • 每行中的整数从左到右按非严格递增顺序排列。
  • 每行的第一个整数大于前一行的最后一个整数。

给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则,返回 false

示例 1:

img

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

示例 2:

img

输入: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

思路

首先,题目要求查询target是否在矩阵中,同时矩阵是有序存储的,从左到右,从上到下增大,即右下 > 左上。

target的状态:

情况一、 target在矩阵外,即小于矩阵最小值,大于矩阵最大值。

情况二、target处于矩阵范围内,同时是矩阵内元素,返回true。

情况三、target处于矩阵范围内,但不是矩阵内元素,返回false。

思路:①、我们先遍历矩阵的行,确认target所处的范围是在哪一行,使用idx记录。

​ ②、我们对该行使用二分法,求出target的具体位置。

二分具体实现:

方法1

  • 我们使用全开区间,即(l, r) 表示范围,

  • 令 l = -1, r = n,即恰好在矩阵长度左右范围 + 1,因为是开区间,不包含l和r本身。

  • 同时在循环中加入判断 if(r - l <= 1) break; 因为要判断target恰好在两个数之间,不是矩阵元素的情况。

代码如下:

题解:

	//方法1public boolean searchMatrix(int[][] matrix, int target) {int m = matrix.length;int n = matrix[0].length;if(target < matrix[0][0] || target > matrix[m - 1][n - 1]) return false;int idx = 0;for(int i = 0; i < m; i ++ ) {if(matrix[i][n - 1] < target) continue;else if(matrix[i][n - 1] >= target) {idx = i;break;}}// 左开右开区间()int l = -1, r = n;boolean flag = false;while(l < r) {int mid = (l + r) / 2;if(matrix[idx][mid] > target) r = mid;else if(matrix[idx][mid] < target) l = mid;else {flag = true;break;}if(r - l <= 1) break;}return flag;}

方法2

  • 使用我们使用全闭区间,即[l, r] 表示区间范围。

  • 令l = 0, r = n - 1。因为是闭区间,我们需要包含l和r本身。

  • 闭区间不需要添加判断,因为l和r有 + 1和 - 1的权值变化,最终会自己跳出循环。

代码如下:

int l = 0, r = n - 1;
boolean flag = false;
while(l <= r) {int mid = (l + r) / 2;if(matrix[idx][mid] > target) r = mid - 1;else if(matrix[idx][mid] < target) l = mid + 1;else {flag = true;break;}
}
return flag;

33、搜素旋转排序数组

问题描述

整数数组 nums 按升序排列,数组中的值 互不相同

在传递给函数之前,nums 在预先未知的某个下标 k0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2]

给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1

你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。

示例 1:

输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4

示例 2:

输入:nums = [4,5,6,7,0,1,2], target = 3
输出:-1

示例 3:

输入:nums = [1], target = 0
输出:-1

提示:

  • 1 <= nums.length <= 5000
  • -104 <= nums[i] <= 104
  • nums 中的每个值都 独一无二
  • 题目数据保证 nums 在预先未知的某个下标上进行了旋转
  • -104 <= target <= 104

思路:

  • 就以[4, 5, 6, 7, 0, 1, 2], target = 8 举例

我们可以明显的看出,如果想要使用二分,就需要找有序的数组,此时我们看到,

  • 该数组有两段局部有序的数组。

  • nums[0]一定大于第二段有序数组的所有数。

我们可以根据第二条性质,使得每次判断都是在有序数组中。

  • 我们实现二分的判断依据就成了,target是否在当前有序数组中,如果不在,那么肯定在该有序数组右(左)边

最开始判断,相等,就直接返回mid.

然后,判断if(nums[0] <= nums[mid])。

  • 这样规定的mid一定处于第一段有序数组中,
    • 内部继续判断if(nums[0] <= target && target < nums[mid]) r = mid - 1
    • else 说明target位于更右边 l = mid + 1

其次,else中

  • 这样的mid一定处于第二段有序数组中,
    • 判断if(nums[mid] < target && target <= nums[n - 1]) l = mid + 1;
    • else 说明target位于更左边 r = mid - 1;

题解

public int search(int[] nums, int target) {if(nums.length == 1) return (nums[0] == target) ? 0 : -1;int n = nums.length;int l = 0, r = n - 1;while(l <= r) {int mid = (l + r) / 2;if(nums[mid] == target) return mid;if(nums[0] <= nums[mid]) {if(nums[0] <= target && target < nums[mid]) r = mid - 1;else l = mid + 1;} else {if(nums[mid] < target && target <= nums[n - 1]) l = mid + 1;else r = mid - 1;}}return -1;
}

http://www.mrgr.cn/news/78914.html

相关文章:

  • 走进科学json版:在 JSON 格式中,字符串值必须使用双引号 “ 来界定,而不能使用单引号 ‘
  • springboot旅游管理系统的设计与实现
  • QT发布ArcGIS QML项目时遇到的问题
  • C# winform非常好用的图表开源控件Scottplot
  • 手机卡限速丨中国移动5G变3G,网速500kb
  • 详解Rust多线程编程
  • 机器学习8-决策树CART原理与GBDT原理
  • 南昌大学(NCU)羽毛球场地预约脚本
  • leeCode算法之最接近的三数之和求解
  • 畅游Diffusion数字人(9):Magic-Me: Identity-Specific Video Customized Diffusion
  • 数据结构——排序第三幕(深究快排(非递归实现)、快排的优化、内省排序,排序总结)超详细!!!!
  • 用到动态库的程序运行过程
  • 繁体字异体字整理(未整理完)
  • LeetCode hot100(自用背诵、部分题目、非最优解)
  • PG 库停库超时异常案例
  • 开源项目 - 人脸关键点检测 facial landmark 人脸关键点 (98个关键点)
  • 4399 Android面试题及参考答案
  • Flutter:页面滚动
  • SCAU期末笔记 - 数据库系统概念
  • 洛谷二分题
  • 鸿蒙技术分享:Navigation页面管理-鸿蒙@fw/router框架源码解析(二)
  • OpenCV_Code_LOG
  • 从0学习JavaScript(2)
  • 【大数据技术基础 | 实验十四】Kafka实验:订阅推送示例
  • Android:生成Excel表格并保存到本地
  • 书生浦语·第四期作业合集