【Java】 剑指offer(53-1) 数字在排序数组中出现的次数
正文
本文参考自《剑指offer》一书,代码采用Java语言。
题目
统计一个数字在排序数组中出现的次数。例如输入排序数组{1, 2, 3, 3,3, 3, 4, 5}和数字3,由于3在这个数组中出现了4次,因此输出4。
思路
分析:对于例子来说,如果采用二分法找到某一个3后,再往前遍历和往后遍历到第一个和最后一个3,在长度为n的数组中有可能出现O(n)个3,因此这样的扫描方法时间复杂度为O(n),效率与从头到尾扫描一样,速度太慢。
这题关键是找到第一个和最后一个3,因此我们尝试改进二分法:中间数字比3大或者小的情况与之前类似,关键是中间数字等于3的情况,这时可以分类讨论如下:
1)如果中间数字的前一个数字也等于3,说明第一个3在前面,继续在前半段查找第一个3;
2)如果中间数字的前一个数字不等于3,说明该位置是第一个3;
3)如果中间数字的后一个数字也等于3,说明最后一个3在后面,继续在后半段查找最后一个3;
2)如果中间数字的后一个数字不等于3,说明该位置是最后一个3;
附加:牛客网上还有一种算法:如果找数字k的次数,由于数组是整数,可以直接找k-0.5和k+0.5应该在数组中哪个位置,这种方法就不用讨论这么多情况了。(不过double类型的大小比较不知道是否会增加太多时间消耗)。
测试算例
1.功能测试(数字出现次数为0、1、2等)
2.边界值测试(数组只有一个数字,查找数字为第一个或者最后一个)
2.特殊测试(null)
Java代码
- //题目:统计一个数字在排序数组中出现的次数。例如输入排序数组{1, 2, 3, 3,
- //3, 3, 4, 5}和数字3,由于3在这个数组中出现了4次,因此输出4。
- public class NumberOfK {
- public int GetNumberOfK(int [] array , int k) {
- if(array==null || array.length<=0)
- return 0;
- int firstK = getFirstK(array,0,array.length-1,k);
- if(firstK == -1)
- return 0;
- int lastK = getLastK(array,firstK,array.length-1,k);
- return lastK-firstK+1;
- }
- private int getFirstK(int[] arr, int start, int end,int k){
- if(start>end)
- return -1;
- int mid = (start+end)>>1;
- if(arr[mid]==k){
- if( mid == 0 ||arr[mid-1]!=k )
- return mid;
- else
- end = mid-1;
- }else if(arr[mid]<k){
- start = mid+1;
- }else{
- end = mid-1;
- }
- return getFirstK(arr,start,end,k);
- }
- private int getLastK(int[] arr, int start, int end,int k){
- if(start>end)
- return -1;
- int mid = (start+end)>>1;
- if(arr[mid]==k){
- if(mid==arr.length-1 || arr[mid+1]!=k )
- return mid;
- else
- start = mid+1;
- }else if(arr[mid]<k){
- start = mid+1;
- }else{
- end = mid-1;
- }
- return getLastK(arr,start,end,k);
- }
- }
解法二:寻找k+0.5和k-0.5的方法:
- public int GetNumberOfK(int [] arr , int k) {
- if(arr==null || arr.length<=0)
- return 0;
- int first = getLoc(arr, k , k-0.5);
- int last = getLoc(arr,k,k+0.5);
- return last-first;
- }
- private int getLoc(int[]arr, int k, double m){ //同样是二分查找
- int start=0,end=arr.length-1;
- while(start<=end){
- int mid=(start+end)>>1;
- if(arr[mid]>m){
- end=mid-1;
- }else{
- start=mid+1;
- }
- }
- return start;
- }
收获
1.同53-3
【Java】 剑指offer(53-1) 数字在排序数组中出现的次数的更多相关文章
- 剑指 offer set 16 数字在排序数组中出现的次数
总结 1. Leetcode 上有一道题, 求某一个数字在有序数组中出现的最左位置和最右位置, 而这道题就是那题的变形
- 用java刷剑指offer(数字在排序数组中出现的次数)
题目描述 统计一个数字在排序数组中出现的次数. 牛客网链接 java代码 //看见有序就用二分法 public class Solution { public int GetNumberOfK(int ...
- 剑指Offer - 九度1349 - 数字在排序数组中出现的次数
剑指Offer - 九度1349 - 数字在排序数组中出现的次数2013-11-23 00:47 题目描述: 统计一个数字在排序数组中出现的次数. 输入: 每个测试案例包括两行: 第一行有1个整数n, ...
- 剑指Offer(三十七):数字在排序数组中出现的次数
剑指Offer(三十七):数字在排序数组中出现的次数 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.n ...
- Go语言实现:【剑指offer】数字在排序数组中出现的次数
该题目来源于牛客网<剑指offer>专题. 统计一个数字在排序数组中出现的次数. 看到排序数组,要想到用二分查找. 先找到最前面的数字k,再找到最后面的数字k,通过下标求出次数. Go语言 ...
- 【剑指Offer面试编程题】题目1349:数字在排序数组中出现的次数--九度OJ
题目描述: 统计一个数字在排序数组中出现的次数. 输入: 每个测试案例包括两行: 第一行有1个整数n,表示数组的大小.1<=n <= 10^6. 第二行有n个整数,表示数组元素,每个元素均 ...
- 数字在排序数组中出现的次数 牛客网 剑指Offer
数字在排序数组中出现的次数 牛客网 剑指Offer 题目描述 统计一个数字在排序数组中出现的次数. class Solution: def GetNumberOfK(self, data, k): i ...
- 【剑指Offer】数字在排序数组中出现的次数 解题报告(Python)
[剑指Offer]数字在排序数组中出现的次数 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interv ...
- 《剑指offer》第五十三题(数字在排序数组中出现的次数)
// 面试题53(一):数字在排序数组中出现的次数 // 题目:统计一个数字在排序数组中出现的次数.例如输入排序数组{1, 2, 3, 3, // 3, 3, 4, 5}和数字3,由于3在这个数组中出 ...
随机推荐
- C# HTTP上传多个文件及传递参数
1.HTTP上传文件及传递参数 #region 6.0 上传多个文件和参数 /// <summary> /// HttpUploadFile /// </summary> // ...
- C# 简单的反射机制实例
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.R ...
- [CQOI2011]放棋子 (DP,数论)
[CQOI2011]放棋子 \(solution:\) 看到这道题我们首先就应该想到有可能是DP和数论,因为题目已经很有特性了(首先题面是放棋子)(然后这一题方案数很多要取模)(而且这一题的数据范围很 ...
- 前端mock数据的几种方式
方式 备注 本地php服务架设 直接输出json 使用在线mock服务 如easyMock.apizza.Rap1\2 , 可以远程协作 本地node服务:koa+mongodb 本地node ...
- 使用sqlmap中tamper脚本绕过waf
使用sqlmap中tamper脚本绕过waf 刘海哥 · 2015/02/02 11:26 0x00 背景 sqlmap中的tamper脚本来对目标进行更高效的攻击. 由于乌云知识库少了sqlmap- ...
- ubuntu16.04+anaconda的安装+解决conda不可用(配置路径)+卸载
首先一点,之前我一直自己安装python,然后直接在python环境下再安装第三方库,但自从另一台电脑重装系统之后,我当时在没有python的情况下直接安装的anaconda,觉得她超级好用(所以如果 ...
- SpringBoot2.X自定义拦截器实战及新旧配置对比(核心知识)
简介: 讲解拦截器使用,Spingboot2.x新版本配置拦截拦截器和旧版本SpringBoot配置拦截器区别讲解 1.@Configuration 继承WebMvcConfigurationAdap ...
- javascript随笔和常见的知识点
1.js中循环中用 return只能停止循环,不能停止到函数的定义部分.所以下面的返回值为1 return 100没有意义,只起到终止循环的目的 function bb() { var sum = 0 ...
- JS如何防止事件冒泡
<div style="height:30px;line-height:30px;background:#FF0;text-align:center;" id="z ...
- MySQL— 进阶
目录 一.视图 二.触发器 三.函数 四.存储过程 五.事务 一.视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集 ...