【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在这个数组中出 ...
随机推荐
- mysql 原理 ~ 二阶段提交协议通说
一 简介: 今天是第二篇,讲解的是mysql的事务日志 二 具体 1 WAL技术(先写日志,再写磁盘) 2 binlog redolog 二阶段提交协议 目的 保持 redo log和binl ...
- 12章 搜索框架ElasticSearch介绍和整合SpringBoot 4节课
1.搜索引擎知识和搜索框架elasticsearch基本介绍 简介:通过京东电商 介绍什么是搜索引擎,和开源搜索框架ElasticSearch6.x新特性介绍 前言:介绍ES的主要特点和使用场 ...
- 【BARTS计划】【Review_Week1】Google Docs 成为青少年们喜爱的聊天 app
BARTS计划 · Review :每周阅读并点评至少一篇英文技术文章. 附原文链接 Google Docs 本是作为协作办公工具存在的,却成了学生们现代版“传纸条”的工具.认真的说,“你永远不知道用 ...
- JS直接if参数的用法
经常在JS中见一些代码直接if(参数),然后参数调用的时候是将元素自己传下去.例如下面代码: <body> <input type="text" name=&qu ...
- ubuntu14.04 提示 卷 文件系统根目录 仅剩余xxx的硬盘空间
- 【Mysql sql inject】POST方法BASE64编码注入write-up
翻到群里的小伙伴发出一道POST型SQL注入题,简单抓包判断出题目需要base64编码后才执行sql语句,为学习下SQL注入出题与闯关的思路+工作不是很忙,所以花点时间玩了一下,哈哈哈哈哈哈哈哈哈 ...
- arm-linux-gcc/ld/objcopy/objdump参数总结【转】
arm-linux-gcc/ld/objcopy/objdump参数总结 转自:http://blog.csdn.net/muyuyuzhong/article/details/7755291 arm ...
- MISC混杂设备 struct miscdevice /misc_register()/misc_deregister()【转】
本文转自:http://blog.csdn.net/angle_birds/article/details/8330407 在Linux系统中,存在一类字符设备,他们共享一个主设备号(10),但此设备 ...
- 八大最安全的Linux发行版,具备匿名功能,做服务器的首选,web,企业服务器等
10 best Linux distros for privacy fiends and security buffs in 2017 Introduction The awesome operati ...
- ES系列十四、ES聚合分析(聚合分析简介、指标聚合、桶聚合)
一.聚合分析简介 1. ES聚合分析是什么? 聚合分析是数据库中重要的功能特性,完成对一个查询的数据集中数据的聚合计算,如:找出某字段(或计算表达式的结果)的最大值.最小值,计算和.平均值等.ES作为 ...