剑指 Offer 53 - I. 在排序数组中查找数字 I(简单)

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

思路:

方法一:哈希

方法二:查找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)同上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值