剑指offer 数字在排序数组中出现的次数

为了方便自己和大家共同学习,本人整理了一些基本解法和比较巧妙的解法~

代码整理自牛客网讨论区:https://www.nowcoder.com/questionTerminal/70610bf967994b22bb1c26f9ae901fa2?f=discussion

剑指offer题型分类及各题的代码及解题思路

题目描述

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

分析:

数组有序,可以用二分查找,但是没必要遍历数组,可以找到这个数字第一个出现的数组下标和最后一个数组出现的数组下标,然后再计算出现的次数。

基于这种思想,我们可以写出递归的代码扎到排序数组的第一个k和最后一个k。

方法一:自己写二分查找

C++实现代码如下:

// 计算数字出现的次数
int GetNumberOfK(vector<int> data ,int k) 
{
	if(data.size() < 1)
	{
		return 0;
	}
	int left = leftLimit(data, k, 0, data.size());
	int right = rightLimit(data, k, -1, data.size() - 1);
	// 找到k在数组中的第一个和最后一个位置,然后相减+1就是个数
	return (right - left + 1);
}
    
// 右边界
int rightLimit(vector<int> data, int k, int left, int right)
{
	while(left < right)
	{
		int mid = (left + right + 1) >> 1;
		if(data[mid] <= k)
		{
			left = mid;
		}
		else
		{
			right = mid - 1;
		}
	}
	return right;
}

// 左边界
int leftLimit(vector<int> data, int k, int left, int right)
{
	while(left < right)
	{
		int mid = (left + right) >> 1;
		if(data[mid] >= k)
		{
			right = mid;
		}
		else
		{
			left = mid + 1;
		}
	}
	return left;
}

 

方法二:利用C++ stl的二分查找(STL equal_range()的用法)

int GetNumberOfK(vector<int> data ,int k) 
{
	
	auto resultPair = equal_range(data.begin(), data.end(),k);
	
	return resultPair.second - resultPair.first;
}

 

方法三:因为data中都是整数,所以可以稍微变一下,不是搜索k的初始和最后出现的位置,而是搜索k-0.5和k+0.5这两个数应该插入的位置,然后相减即可。

int GetNumberOfK(vector<int> data ,int k) 
{
	int start = biSearch(data, k-0.5);	//数字第一次出现的数组下标
	int end = biSearch(data, k+0.5);	//数字最后一次出现的后面一个数字的下标
	return  end - start;
}

int biSearch(const vector<int> & data, double num)
{
	int s = 0, e = data.size()-1; //s为二分查找数组的第一个数字下标,e为最后一个数字的下标
	
	while(s <= e)
	{
		int mid = (e - s)/2 + s; //中间数字的下标
		
		if(data[mid] < num)	//s右移,往右查找
			s = mid + 1;
		else if(data[mid] > num) //e往左移,往左查找
			e = mid - 1;
	}
	return s;
}

相似的题目:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值