【剑指Offer】53 - l. 在排序数组中找数字

题目描述

统计一个数字在排序数组中出现的次数。

示例1:

输入:nums = [5,7,7,8,8,10],target = 8
输出:2

示例2:

输入:nums = [5,7,7,8,8,10],target = 6
输出:0

提示:

0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums 是一个非递减数组
-109 <= target <= 109

解题思路

此题主要考察二分查找变体问题,首先查找第一个值等于给定值的元素,拿到第一个值的下标后就可以往后遍历直到不等于给定值的元素就退出。我们可以定义一个计数器count来计算循环次数,此时count的值就是我们要的结果。

代码实现

1. 查找第一个值等于给定值的元素

public static int getPos(int[] nums, int target) {
	int low = 0;
	int high = nums.length - 1;
	while (low <= high) {
		// 等效于(low+high)/2,因为计算机对位运算更快
		int mid = low + ((high - low) >> 1);
		if (nums[mid] > target)
			high = mid - 1;
		else if (nums[mid] < target)
			low = mid + 1;
		else {
			/*
			 * nums[mid]与要查找的value的大小关系有3种情况:大于、小于和等于。大于和小于这两种情况
			 * 很好理解。那么,当nums[mid]==value的时候,nums[mid]就是我们要找的元素。如何确定这
			 * 个nums[mid]值是不是第一个呢?
			 * 1.如果mid==0,也就是说,这个元素已经是数组的第一个元素,那么它肯定就是我们要找的第
			 * 一个值等于给定值的元素;
			 * 2.如果mid!=0,但nums[mid]的前一个元素nums[mid - 1]不等于target,那么说明
			 * nums[mid]就是我们要找的第一个值等于给定值的元素。
			 */
			if ((mid == 0) || (nums[mid - 1] != target))
				return mid;
			else
				// 否则说明前面还有元素与target相等,我们就继续查找,因为要查找的元素肯定出现在
				// [low, mid - 1]区间。
				high = mid - 1;
		}
	}
	return -1;
}

2. 遍历

public int search(int[] nums, int target) {
	int pos = getPos(nums, target)
	if (pos == -1)
		return 0;
	int count = 0;
	while (pos < nums.length && nums[pos] == target) {
		count++;
		pos++;
	}
	return count;
}

总结

  1. 遇到像这种有序查找问题首先想到的是二分查找,一般都是考察二分查找的变体问题。
  2. 二分查找算法时间复杂度是O(logn)。
  3. 二分查找的底层必须依赖数组,并且要求数据是静态有序的。
  4. 适用于较大规模的数据的查找问题。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值