目录
题目描述
数字在排序数组中出现的次数。
统计一个数字在排序数组中出现的次数。例如输入排序数组{1,2,3,3,3,4,5}和数字3,由于3在这个数组中出现了4次,因此输出4。
测试用例
- 功能测试(数组中包含要查找的数字;数组中没有要查找的数字;要查找的数字在数组中出现一次/多次)
- 边界值测试(查找数组中的最大值、最小值;数组中只有一个数字)
- 特殊输入测试(表示数组的指针为空指针)
题目考点
- 考察应聘者的只是迁移能力。
- 考察应聘者对二分查找算法的理解程度。
解题思路
一看到在排序(排序数组,一样的数字是挨到一起的)数组中查找,大家一定能想到二分查找法,但是怎么用可以减少复杂度.
- 利用二分查找法找出最早(左)出现的k的下标:
如果中位数为k,看中位数前一个是否为k。是的话,说明要继续在数组前半段寻找第一个k(递归);不是的话,说明当前中位数为第一个k,返回当前下标;
2.利用二分查找法找出最晚(右)出现的k的下标
同理,如果中位数为k,看中位数后一个是否为k。是的话,说明要继续在数组后半段寻找最后一个k(递归);不是的话,说明当前中位数为第一个k,返回当前下标;
参考解题
public class Solution {
// 排序数组中数字出现次数
// 排序数组,查找,二分查找,确定第一个和最后一个k的位置
public int GetNumberOfK(int [] array , int k) {
// 异常
if(array == null || array.length == 0){
return 0;
}
int number = 0;
int first = GetFirstKIndex(array, k, 0, array.length - 1);
int last = GetLastKIndex(array, k, 0, array.length - 1);
if(first != -1 && last != -1){
number = last - first + 1;
}
return number;
}
// 二分查找改变,找到中位数之后再进行一次比较
// ------第一个k下标----------------
public int GetFirstKIndex(int[] array, int k, int start, int end){
// 异常
if(start > end || start < 0 || end > array.length - 1){
return -1;
}
int midIndex = (start + end)>>1;
int midData = array[midIndex];
if(midData == k ){
if( (midIndex > 0 && array[midIndex - 1] != k )
|| midIndex == 0){
// 中位数为k,中位数前一位不是k,所以中位数为第一个k
return midIndex;
}else{
end = midIndex - 1;
}
}else if(midData > k){
end = midIndex - 1;
}else{
start = midIndex + 1;
}
return GetFirstKIndex(array, k, start, end);
}
// ------最后一个k下标--------------------------------
public int GetLastKIndex(int[] array, int k, int start, int end){
// 异常
if(start > end || start < 0 || end > array.length-1){
return -1;
}
int midIndex = (start + end) >> 1;
int midData = array[midIndex];
if(midData == k ){
if((midIndex < array.length - 1 && array[midIndex + 1] != k )
|| midIndex == array.length - 1){
// 中位数为k,中位数后一位不是k,所以中位数为最后一个k
return midIndex;
}else{
start = midIndex + 1;
}
}else if(array[midIndex] > k){
end = midIndex - 1;
}else{
start = midIndex + 1;
}
return GetLastKIndex(array, k, start, end);
}
}
排错记录
if( (midIndex > 0 && array[midIndex - 1] != k )
|| midIndex == 0)
在书写这一句条件的时候,前后顺序不一样会导致索引溢出错误。先判断midIndex > 0成立之后,再有表达式array[midIndex - 1] 的正确性。