1、题目描述
给定一个长度为 n 的非降序数组和一个非负数整数 k ,要求统计 k 在数组中出现的次数
数据范围:0 \le n \le 1000 , 0 \le k \le 1000≤n≤1000,0≤k≤100,数组中每个元素的值满足 0 \le val \le 1000≤val≤100
要求:空间复杂度 O(1)O(1),时间复杂度 O(logn)O(logn)
2、算法分析
一个for循环就可以了。但是效率非常低。
另一种方法使用的是二分查找。找到array[mid] == k。
然后遍历mid左边的是否等于k,遍历mid右边的是否等于k。
当然计数count++;
3、代码实现
①for循环,直接判断
public class Solution {
public int GetNumberOfK(int [] array , int k) {
if(array.length == 0 || array == null){
return 0;
}
int count = 0;
for(int i = 0;i < array.length;i++){
if(array[i] == k){
count++;
}
}
return count;
}
}
②二叉查找计数
public class Solution {
public int GetNumberOfK(int [] array , int k) {
if(array.length == 0 || array == null){
return 0;
}
int result = 0;
int low = 0;
int high = array.length-1;
int mid = 0;
// 遍历
while(low <= high){
mid = low + (high - low) / 2;
// 找到等于k的值的话,计数++
if(k == array[mid]){
result++;
// 找到了,跳出循环,不需要比较了。
break;
}else if(k < array[mid]){
high = mid - 1;
}else{
low = mid + 1;
}
}
// 计数mid后面等于k的情况
for(int i = mid + 1;i < array.length;i++){
if(array[i] == k){
result++;
}else{
break;
}
}
// 计数mid前面等于k的情况
for(int j = mid-1;j >= 0;j--){
if(array[j] == k){
result++;
}else{
break;
}
}
return result;
}
}
比较一下,他们的效率是不一样的,当然二分查找效率更高。
因为for循环遍历了整个数组,而二分查找值遍历了等于k的那一段。