思路:
方法一:哈希
方法二:查找target的左边界和有边界,相减即可得到长度,也就是出现的次数

方法三:
取target的前一个数字,求其右边界

代码:
方法一:
class Solution {
public int search(int[] nums, int target) {
Map<Integer,Integer> map=new HashMap<>();
for(int num:nums){
if(num==target){
map.put(target,map.getOrDefault(target,0)+1);
}
}
return map.getOrDefault(target,0);
}
}
方法二:
class Solution {
public int search(int[] nums, int target) {
int i=0,j=nums.length-1;
int left=0,right=0;
//右边界
while(i<=j){
int m=i+(j-i)/2;
if(nums[m]<=target){
i=m+1;
}
else{
//??
j=m-1;
}
}
right=j;
//没找到右边界,不需要再往下找左边界了,直接返回0
//说明不存在target
if(j>=0&&nums[j]!=target){
return 0;
}
i=0;
j=nums.length-1;
//找左边界
while(i<=j){
int m=i+(j-i)/2;
if(nums[m]<target){
i=m+1;
}
else{
j=m-1;
}
}
left=i;
return right-left+1;
}
}
方法三:
class Solution {
public int search(int[] nums, int target) {
int r1=binary(nums,target);
int r2=binary(nums,target-1);
return r1-r2;
}
private int binary(
int[] nums,
int target
){
int i=0,j=nums.length-1;
while(i<=j){
//取中点要在循环内
int m=i+(j-i)/2;
//统一找右边界
if(nums[m]<=target){
i=m+1;
}
else{
j=m-1;
}
}
return j;
}
}
分解:
1)使用二分查找可以提升一点时间复杂度
方法二:
查找右边界与左边界稍有一点不同:
右边界的判断条件:
nums[m]<=target
左边界的判断条件:
nums[m]<target
一个"="的区别
3)当查询第一个边界时,如果不存在target的值,可以直接返回0,说明不存在此元素,可以停止不继续往下查询下一个边界了
if(j>=0&&nums[j]!=target){
return 0;
}
4)方法三:
取target的前一个数字,求其右边界

5)注意: j=m-1,而不是m
if(nums[m]<=target){
i=m+1;
}
else{
j=m-1;
}
复杂度分析:
方法一:
时间复杂度:O(N)要遍历N个元素
空间复杂度:O(1)哈希存储1个元素即可
方法二、三:
时间复杂度:O(logN)二分查找是对数级别复杂度
空间复杂度:O(1)同上

这篇博客探讨了在排序数组中查找数字出现次数的三种方法:哈希、查找左右边界以及寻找前一个数字的右边界。通过二分查找优化了时间复杂度,详细分析了每种方法的时间和空间复杂度。

被折叠的 条评论
为什么被折叠?



