【LeetCode】剑指 Offer 53 - I. 在排序数组中查找数字 I
【LeetCode】剑指 Offer 53 - I. 在排序数组中查找数字 I
文章目录
- 【LeetCode】剑指 Offer 53 - I. 在排序数组中查找数字 I
- 一、二分法
- 总结
一、二分法
排序数组 nums 中的所有数字 target 形成一个窗口,记窗口的左/右边界索引分别为 left 和 right,分别对应窗口左边/右边的首个元素
本题要求统计数字 target 的出现次数,可转化为:使用二分法分别找到左边界 left 和右边界 right,易得数字 target 的数量为 right - left - 1
算法解析:
- 初始化:左边界 i = 0,右边界 j = len(nums) - 1
- 循环二分:当闭区间 [i,j] 无元素时跳出
- 计算中点 m = (i + j) / 2(向下取整)
- 若 nums[m] < target,则 target 在闭区间 [m + 1,j] 中,因此执行 i = m + 1
- 若 nums[m] > target,则 target 在闭区间 [i,m - 1] 中,因此执行 j = m - 1
- 若 nums[m] = target,则右边界 right 在闭区间 [m + 1,j] 中。左边界 left 在闭区间 [i,m-1] 中。因此分为以下两种情况:
- 若查找右边界 right,则执行 i = m + 1(跳出时 i 指向右边界)
- 若查找左边界 left,则执行 j = m -1(跳出时 j 指向左边界)
- 返回值:应用两次二分,分别查找 right 和 left,最终返回 right - left - 1即可
效率优化:
以下优化基于:查找完右边界 right = i 后,则 nums[j] 指向最右边的 target(若存在)
- 查找完右边界后,可用 nums[j] = j 判断数组中是否包含 target,若不包含则直接提前返回 0,无需后续查找左边界
- 查找完右边界后,左边界 left 一定在闭区间 [0,j] 中,因此直接从此区间开始二分查找即可
class Solution{public int search(int[] nums, int target){//搜索右边界 rightint i = 0;int j = nums.length - 1;while(i <= j){int m = (i + j) / 2;if(nums[m] <= target) i = m + 1;else j = m - 1;}int right = i;//若数组中无 target,则提前返回if(j >= 0 && nums[j] != target) return 0;//搜索左边界 righti = 0;j = nums.length - 1;while(i <= j){int m = (i + j) / 2;if(nums[m] < target) i = m + 1;else j = m - 1;}int left = j;return right - left - 1;}
}
以上代码显得比较臃肿(两轮二分查找代码冗余)。为简化代码,可将二分查找右边界 right 的代码封装至函数 helper()
如上图所示,由于数组 nums 中元素都为整数,因此可以分别二分查找 target 和 target - 1 的右边界,将两结果相减并返回即可
本质上看,helper() 函数旨在查找数字 tar 在数组 nums 中的插入点,且若数组中存在值相同的元素,则插入到这些元素的右边
class Solution{public int search(int[] nums,int target){return helper(nums, target) - helper(nums, target - 1);}public int helper(int[] nums, int tar){int i = 0;int j = nums.length - 1;while(i <= j){int m = (i + j) / 2;if(nums[m] <= tar) i = m + 1;else j = m - 1;}return i;}
}
- 时间复杂度 O(logN),二分法为对数级别复杂度
- 空间复杂度 O(1),几个变量使用常数大小的额外空间
总结
难点在于边界怎么寻找,多思考即可
【LeetCode】剑指 Offer 53 - I. 在排序数组中查找数字 I相关推荐
- Leetcode 剑指 Offer 53 - I. 在排序数组中查找数字 I (每日一题 20210928)
统计一个数字在排序数组中出现的次数.示例 1:输入: nums = [5,7,7,8,8,10], target = 8 输出: 2 示例 2:输入: nums = [5,7,7,8,8,10], t ...
- 剑指 Offer 53 - I. 在排序数组中查找数字 I(二分法)
统计一个数字在排序数组中出现的次数. 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: 2 示例 2: 输入: nums = [5,7,7,8,8,10] ...
- 【算法】剑指 Offer 53 - I. 在排序数组中查找数字 I
1.概述 统计一个数字在排序数组中出现的次数. 示例 1: 输入: nums = [5,7,7,8,8,10], target =
- LeetCode-剑指 Offer 53 - I. 在排序数组中查找数字 I
剑指 Offer 53 - I. 在排序数组中查找数字 I 思路一:二分单边 + 线性扫描 先用一次二分查找找到边界,再再边界里面寻找目标值 class Solution {public:int se ...
- 剑指Offer - 面试题53 - I. 在排序数组中查找数字 I(二分查找的变形版本)
1. 题目 统计一个数字在排序数组中出现的次数. 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: 2示例 2: 输入: nums = [5,7,7,8, ...
- leetcode剑指 Offer 53 - II. 0~n-1中缺失的数字(二分查找)
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0-n-1之内.在范围0-n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字. 示例 1: 输入: [0,1,3 ...
- 【剑指offer】面试题53 - 1:在排序数组中查找数字 I(java)
统计一个数字在排序数组中出现的次数. 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: 2 示例 2: 输入: nums = [5,7,7,8,8,10] ...
- 剑指offer面试题53 - I. 在排序数组中查找数字 I(二分查找)
题目描述 统计一个数字在排序数组中出现的次数. 思路 详见链接 代码 class Solution:def search(self,nums:[int],target:int)->int:i, ...
- 【算法】剑指 Offer 53 - II. 0~n-1中缺失的数字
1.概述 剑指 Offer 53 - II. 0-n-1中缺失的数字 一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0-n-1之内.在范围0-n-1内的n个数字中有且只有一 ...
最新文章
- pta l2-7(家庭房产)
- 【深度学习】初识tensorflow之分布式训练
- 任务和特权级保护(三)——《x86汇编语言:从实模式到保护模式》读书笔记34
- GDCM:读取gdcm::DataSetHelper的测试程序
- ASP.NET常见面试题及答案(130题)
- 【原创】Maven cobertura整合多个子项目下的单测覆盖率报告
- 红橙Darren视频笔记 Handler源码简析与handler框架模拟 ThreadLocal
- 图象关于y轴对称是什么意思_关于新风系统的全热交换到底是什么意思?艾尔文技术解读篇...
- (大家发表一下看法)微软研发智能系统 可通过电脑24小时监控员工
- 混淆的艺术-(苍井空变凤姐)Proguard源码分析(二)Proguard参数解析
- matlab的图片压缩两种方法(DCT方法与行程编码压缩方法)
- VMware16安装Win11虚拟机(最全步骤+踩坑)
- 20191009 csp-s模拟T3(并查集)
- html页面设置过期时间,meta标签http-equiv=Expires属性写法及用法
- 使用 Marvelous Designer 为DAZ Studio 的 Genesis8 Female做衣服 1
- CSR867x — sink工程的编译与下载(run)
- 【Benewake(北醒) 】短距 TFmini Plus 12m介绍以及资料整理
- ThinkCMF图片上传
- oracle 中文乱码 java_oracle ---中文乱码问题
- Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭
热门文章
- php中的变量函数,PHP中的一些路径变量或函数
- seg代码配置的踩坑记录
- Android开发工具Android Studio、Android SDK和Genymotion完全配置
- python3 类的相关内容
- Asp.Net Core发布绑定域名和端口
- 云计算之路-阿里云上:4000IOPS的RDS+16核CPU的负载均衡
- 使用libvirt技术监控虚拟机资源利用情况
- 服务器显示转速负数,Moldflow使用常见问题及解决方案
- android底部导航栏网络请求有冲突,Android 自定义底部导航栏 CustomizeTabLayout(支持访问网络图片、本地图片)...
- (65)DDR工作效率?