正文

本文参考自《剑指offer》一书,代码采用Java语言。

更多:《剑指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

  

更多:《剑指Offer》Java实现合集  

  

【Java】 剑指offer(53-1) 数字在排序数组中出现的次数的更多相关文章

  1. 剑指 offer set 16 数字在排序数组中出现的次数

    总结 1. Leetcode 上有一道题, 求某一个数字在有序数组中出现的最左位置和最右位置, 而这道题就是那题的变形

  2. 用java刷剑指offer(数字在排序数组中出现的次数)

    题目描述 统计一个数字在排序数组中出现的次数. 牛客网链接 java代码 //看见有序就用二分法 public class Solution { public int GetNumberOfK(int ...

  3. 剑指Offer - 九度1349 - 数字在排序数组中出现的次数

    剑指Offer - 九度1349 - 数字在排序数组中出现的次数2013-11-23 00:47 题目描述: 统计一个数字在排序数组中出现的次数. 输入: 每个测试案例包括两行: 第一行有1个整数n, ...

  4. 剑指Offer(三十七):数字在排序数组中出现的次数

    剑指Offer(三十七):数字在排序数组中出现的次数 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.n ...

  5. Go语言实现:【剑指offer】数字在排序数组中出现的次数

    该题目来源于牛客网<剑指offer>专题. 统计一个数字在排序数组中出现的次数. 看到排序数组,要想到用二分查找. 先找到最前面的数字k,再找到最后面的数字k,通过下标求出次数. Go语言 ...

  6. 【剑指Offer面试编程题】题目1349:数字在排序数组中出现的次数--九度OJ

    题目描述: 统计一个数字在排序数组中出现的次数. 输入: 每个测试案例包括两行: 第一行有1个整数n,表示数组的大小.1<=n <= 10^6. 第二行有n个整数,表示数组元素,每个元素均 ...

  7. 数字在排序数组中出现的次数 牛客网 剑指Offer

    数字在排序数组中出现的次数 牛客网 剑指Offer 题目描述 统计一个数字在排序数组中出现的次数. class Solution: def GetNumberOfK(self, data, k): i ...

  8. 【剑指Offer】数字在排序数组中出现的次数 解题报告(Python)

    [剑指Offer]数字在排序数组中出现的次数 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interv ...

  9. 《剑指offer》第五十三题(数字在排序数组中出现的次数)

    // 面试题53(一):数字在排序数组中出现的次数 // 题目:统计一个数字在排序数组中出现的次数.例如输入排序数组{1, 2, 3, 3, // 3, 3, 4, 5}和数字3,由于3在这个数组中出 ...

随机推荐

  1. EF crud操作

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  2. Error while executing topic command : Replication factor: 2 larger than available brokers: 0.

    [root@hdp1 /mnt/software/maxwell-1.19.4]#kafka-topics.sh --zookeeper hdp1,hdp2,hdp3:2181 --create -- ...

  3. 【金色】种瓜得瓜,种豆得豆 Gym - 102072H (线段树)

    题目链接:https://cn.vjudge.net/problem/Gym-102072H 题目大意:中文题目 具体思路:通过两棵线段树来维护,第一棵线段树来维护当前坐标的点的日增长速度(默认每一年 ...

  4. mysql案例 ~ 主从复制延迟处理(3)

    一 简介:今天咱们来汇总下如何避免主从延迟 二 方案: 1 集群硬件配置统一,磁盘组更好(SSD最佳),更大的内存 2 linux系统+mysql的配置参数已经优化 3 mysql从库没有任何慢语句进 ...

  5. Docker相关

    1.理念 通过对应用组件的封装.分发.部署.运行等生命周期的管理,使用户的App(可以是一个Web应用或数据库应用等)及其运行环境能够做到“一次封装,处处运行”. 2.一句话总结 解决运行环境和配置问 ...

  6. canny 算子python实现

    1. Canny介绍 Canny算子与Marr(LoG)边缘检测方法类似,也属于是先平滑后求导数的方法.John Canny研究了最优边缘检测方法所需的特性,给出了评价边缘检测性能优劣的三个指标: 1 ...

  7. passwd: Have exhausted maximum number of retries for service【转】

    使用命令passwd修改密码时,遇到如下问题: # echo 'utf8'|passwd zhangsan --stdin Changing password for user zhangsan. p ...

  8. activit流程引擎启动流程报错

    代码如下: 目录结构 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); @Test public void ...

  9. centos6.5环境基于conga的web图形化界面方式配置rhcs集群

    一.简介 RHCS 即 RedHat Cluster Suite ,中文意思即红帽集群套件.红帽集群套件(RedHat Cluter Suite, RHCS)是一套综合的软件组件,可以通过在部署时采用 ...

  10. 深度学习Bible学习笔记:第六章 深度前馈网络

    第四章 数值计算(numerical calculation)和第五章 机器学习基础下去自己看. 一.深度前馈网络(Deep Feedfarward Network,DFN)概要: DFN:深度前馈网 ...