【LeetCode】剑指 Offer 53 - I. 在排序数组中查找数字 I

文章目录

  • 【LeetCode】剑指 Offer 53 - I. 在排序数组中查找数字 I
  • 一、二分法
  • 总结

一、二分法

排序数组 nums 中的所有数字 target 形成一个窗口,记窗口的左/右边界索引分别为 left 和 right,分别对应窗口左边/右边的首个元素

本题要求统计数字 target 的出现次数,可转化为:使用二分法分别找到左边界 left 和右边界 right,易得数字 target 的数量为 right - left - 1

算法解析:

  1. 初始化:左边界 i = 0,右边界 j = len(nums) - 1
  2. 循环二分:当闭区间 [i,j] 无元素时跳出
    1. 计算中点 m = (i + j) / 2(向下取整)
    2. 若 nums[m] < target,则 target 在闭区间 [m + 1,j] 中,因此执行 i = m + 1
    3. 若 nums[m] > target,则 target 在闭区间 [i,m - 1] 中,因此执行 j = m - 1
    4. 若 nums[m] = target,则右边界 right 在闭区间 [m + 1,j] 中。左边界 left 在闭区间 [i,m-1] 中。因此分为以下两种情况:
      1. 若查找右边界 right,则执行 i = m + 1(跳出时 i 指向右边界)
      2. 若查找左边界 left,则执行 j = m -1(跳出时 j 指向左边界)
  3. 返回值:应用两次二分,分别查找 right 和 left,最终返回 right - left - 1即可

效率优化:
以下优化基于:查找完右边界 right = i 后,则 nums[j] 指向最右边的 target(若存在)

  1. 查找完右边界后,可用 nums[j] = j 判断数组中是否包含 target,若不包含则直接提前返回 0,无需后续查找左边界
  2. 查找完右边界后,左边界 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相关推荐

  1. 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 ...

  2. 剑指 Offer 53 - I. 在排序数组中查找数字 I(二分法)

    统计一个数字在排序数组中出现的次数. 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: 2 示例 2: 输入: nums = [5,7,7,8,8,10] ...

  3. 【算法】剑指 Offer 53 - I. 在排序数组中查找数字 I

    1.概述 统计一个数字在排序数组中出现的次数. 示例 1: 输入: nums = [5,7,7,8,8,10], target =

  4. LeetCode-剑指 Offer 53 - I. 在排序数组中查找数字 I

    剑指 Offer 53 - I. 在排序数组中查找数字 I 思路一:二分单边 + 线性扫描 先用一次二分查找找到边界,再再边界里面寻找目标值 class Solution {public:int se ...

  5. 剑指Offer - 面试题53 - I. 在排序数组中查找数字 I(二分查找的变形版本)

    1. 题目 统计一个数字在排序数组中出现的次数. 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: 2示例 2: 输入: nums = [5,7,7,8, ...

  6. leetcode剑指 Offer 53 - II. 0~n-1中缺失的数字(二分查找)

    一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0-n-1之内.在范围0-n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字. 示例 1: 输入: [0,1,3 ...

  7. 【剑指offer】面试题53 - 1:在排序数组中查找数字 I(java)

    统计一个数字在排序数组中出现的次数. 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: 2 示例 2: 输入: nums = [5,7,7,8,8,10] ...

  8. 剑指offer面试题53 - I. 在排序数组中查找数字 I(二分查找)

    题目描述 统计一个数字在排序数组中出现的次数. 思路 详见链接 代码 class Solution:def search(self,nums:[int],target:int)->int:i, ...

  9. 【算法】剑指 Offer 53 - II. 0~n-1中缺失的数字

    1.概述 剑指 Offer 53 - II. 0-n-1中缺失的数字 一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0-n-1之内.在范围0-n-1内的n个数字中有且只有一 ...

最新文章

  1. pta l2-7(家庭房产)
  2. 【深度学习】初识tensorflow之分布式训练
  3. 任务和特权级保护(三)——《x86汇编语言:从实模式到保护模式》读书笔记34
  4. GDCM:读取gdcm::DataSetHelper的测试程序
  5. ASP.NET常见面试题及答案(130题)
  6. 【原创】Maven cobertura整合多个子项目下的单测覆盖率报告
  7. 红橙Darren视频笔记 Handler源码简析与handler框架模拟 ThreadLocal
  8. 图象关于y轴对称是什么意思_关于新风系统的全热交换到底是什么意思?艾尔文技术解读篇...
  9. (大家发表一下看法)微软研发智能系统 可通过电脑24小时监控员工
  10. 混淆的艺术-(苍井空变凤姐)Proguard源码分析(二)Proguard参数解析
  11. matlab的图片压缩两种方法(DCT方法与行程编码压缩方法)
  12. VMware16安装Win11虚拟机(最全步骤+踩坑)
  13. 20191009 csp-s模拟T3(并查集)
  14. html页面设置过期时间,meta标签http-equiv=Expires属性写法及用法
  15. 使用 Marvelous Designer 为DAZ Studio 的 Genesis8 Female做衣服 1
  16. CSR867x — sink工程的编译与下载(run)
  17. 【Benewake(北醒) 】短距 TFmini Plus 12m介绍以及资料整理
  18. ThinkCMF图片上传
  19. oracle 中文乱码 java_oracle ---中文乱码问题
  20. Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭

热门文章

  1. php中的变量函数,PHP中的一些路径变量或函数
  2. seg代码配置的踩坑记录
  3. Android开发工具Android Studio、Android SDK和Genymotion完全配置
  4. python3 类的相关内容
  5. Asp.Net Core发布绑定域名和端口
  6. 云计算之路-阿里云上:4000IOPS的RDS+16核CPU的负载均衡
  7. 使用libvirt技术监控虚拟机资源利用情况
  8. 服务器显示转速负数,Moldflow使用常见问题及解决方案
  9. android底部导航栏网络请求有冲突,Android 自定义底部导航栏 CustomizeTabLayout(支持访问网络图片、本地图片)...
  10. (65)DDR工作效率?