JZ53 数字在升序数组中出现的次数
描述:
给定一个长度为 n 的非降序数组和一个非负数整数 k ,要求统计 k 在数组中出现的次数
数据范围:1000 ≤ n ≤ 1000, 0 ≤ k ≤ 100,数组中每个元素的值满足 0 ≤ val ≤ 100
要求:空间复杂度 O(1),时间复杂度 O(logn)
解析:
题干中的非降序数组指升序数组 --> 即为有序数组
既然为有序数组,那就方便我们去对它做一些操作了。
方法思路:
方法一:暴力法
思路:
直接对数组进行遍历,有一个符合条件的非负整数就对定义的计数参数加一
直到遍历完毕后,返回计数参数即可。
时间复杂度:O(n) -- 一次遍历循环
空间复杂度:O(1)
方法二:二分法
分治思想:
分治即“分而治之”
“分”指的是将一个大而复杂的问题划分成多个性质相同但是规模更小的子问题,子问题继续按照这样划分,直到问题可以被轻易解决;
“治”指的是将子问题单独进行处理。
经过分治后的子问题,需要将解进行合并才能得到原问题的解,因此整个分治过程经常用递归来实现
思路:
二分查找可以降低时间复杂度,从而提高代码执行效率。
利用二分查找结合分治思想将查询的值加减0.5,从而使得查询的值两次左边界得以确定,两次左边界确定后进行加减即可得到查询值出现在数组中的次数。
时间复杂度:O(log2n)
空间复杂度:O(1)
- Java相关代码:
public int getNumberOfK02(int[] array, int k) {
return binarySearch(array, k + 0.5) - binarySearch(array, k - 0.5);
}
private int binarySearch(int[] arr, double number) {
int left = 0;
int right = arr.length - 1;
int mid;
while (left <= right) {
mid = (left + right) >>> 1;
if (arr[mid] < number) {
left = mid + 1;
}
if (arr[mid] > number) {
right = mid - 1;
}
}
return left;
}
个人学习后的总结,如有不足之处,请及时指正,谢谢。