剑指offer--(5)数字在排序数组中出现的次数--Java描述

写在前面:

    首先,这道问题,当我们看到"排序数组"这四个字的时候,我们首先想到的应该是使用二分法,但是传统的二分法,只能让我们找到一个索引,当数组中出现多个相同元素的时候,返回的索引不确定。eg:int [] str=new int [] {3,3,3}; 而我们,为了找到数字出现的次数,就要找到这个数字第一个出现的索引firstKey和最后一次出现的索引lastKey,最后的结果=lastKey-firstKey+1.

    针对,以上的特点,我们就要对二分法进行一些改进,避免,索引取到了中间的元素。

代码实现:

public static int GetNumberOfK(int[] array, int k) {
		// 看到有序,首先要想起二分法
		if (array.length == 0) {
			return 0;
		}
		int firstKey = findFirstKey(array, k, 0, array.length - 1); // 找到第一个索引
		int lastKey = findLastKey(array, k, 0, array.length - 1);  // 找到最后一个索引
		if (firstKey != -1 && lastKey != -1) {
			return lastKey - firstKey + 1;
		}
		return 0;
	}

	public static int findFirstKey(int[] array, int k, int low, int high) {
		// 等价于 mid = (low + high)/2;
		int mid = (low + high) >> 1;// 这样效率更高
		while (low <= high) {
			if (array[mid] > k) {
				high = mid - 1;
			} else if (array[mid] < k) {
				low = mid + 1;
			} else if (mid - 1 > 0 && array[mid - 1] == k) {
				// 避免找到的是中间的数
				high = mid - 1;
			} else {
				return mid;
			}
			mid = (low + high) >> 1;
		}
		return -1;
	}

	public static int findLastKey(int[] array, int k, int low, int high) {

		int mid = (low + high) >> 1;
		while (low <= high) {
			if (array[mid] > k) {
				high = mid - 1;
			} else if (array[mid] < k) {
				low = mid + 1;
			} else if (mid + 1 < array.length && array[mid + 1] == k) {
				low = mid + 1;
			} else {
				return mid;
			}
			mid = (low + high) >> 1;
		}
		return -1;
	}

总结:

    针对二分法来说,也可以使用递归来实现,为了方便大家的理解,本文使用了循环的方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值