重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
给定一个长度为 n 的非降序数组和一个非负数整数 k ,要求统计 k 在数组中出现的次数
数据范围:1000 ≤ n ≤ 1000, 0 ≤ k ≤ 100,数组中每个元素的值满足 0 ≤ val ≤ 100
要求:空间复杂度 O(1),时间复杂度 O(logn)
解析:题干中的非降序数组指升序数组 -->即为有序数组
既然为有序数组,那就方便我们去对它做一些操作了。
方法思路:
方法一:暴力法思路:
直接对数组进行遍历,有一个符合条件的非负整数就对定义的计数参数加一
直到遍历完毕后,返回计数参数即可。
时间复杂度:O(n) -- 一次遍历循环
空间复杂度:O(1)
public int getNumberOfK01(int[] array, int k) {int sum = 0;
for (int each : array) {if (each == k) {sum++;
}
}
return sum;
}
分治思想:
分治即“分而治之”
“分”指的是将一个大而复杂的问题划分成多个性质相同但是规模更小的子问题,子问题继续按照这样划分,直到问题可以被轻易解决;
“治”指的是将子问题单独进行处理。
经过分治后的子问题,需要将解进行合并才能得到原问题的解,因此整个分治过程经常用递归来实现
思路:
二分查找可以降低时间复杂度,从而提高代码执行效率。
利用二分查找结合分治思想将查询的值加减0.5,从而使得查询的值两次左边界得以确定,两次左边界确定后进行加减即可得到查询值出现在数组中的次数。
时间复杂度:O(log2n)
空间复杂度:O(1)
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;
}
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网站建设哪家好,找成都创新互联公司!专注于网页设计、网站建设、微信开发、微信小程序、集团企业网站建设等服务项目。为回馈新老客户创新互联还提供了大同免费建站欢迎大家使用!