数字在排序数组中出现的次数

题目:统计一个数字在排序数组中出现的次数。例如,输入排序数组{1,2,3,3,3,4,5,6}和数字3,由于3在数组中出现了3次,因此输出次数3。

方案一:时间复杂度为O(n)

  1. 先用二分查找找到3;
  2. 在3的两边顺序扫描,分别找出第一个3和最后一个3的位置;
  3. 最后用最后一个3的位置减去第一个3的位置加1,就能得出3在数组中的个数。

方案二:时间复杂度为O(log2(n))

  1. 先用二分查找的方法找到3;
  2. 然后再用二分查找的方法找到第一个3和最后一个3的位置;
  3. 最后用最后一个3的位置减去第一个3的位置加1,就能得出3在数组中出现的次数。

方案二与方案一相同的是:都用二分查找找到第一个3;

方案一与方案二不同的是:方案一用顺序查找的方法找到3的首尾位置,而方案二用二分查找的方法找到3的首尾位置。

程序如下:

#include<stdio.h>
#include<stdlib.h>

//向查找数的前面查找,获取第一个查找数的位置
int GetFirstIndex(int arr[], int len, int K, int start, int end)
{
	//避免栈溢出
	if (start > end)
	{
		return -1;
	}

	//求中间数
	int mid = start + ((end - start) >> 1);

	//当中间值等于查找数时
	if (arr[mid] == K)
	{
		//当查找数与前面一个元素的值不相同时,返回此时的下标
		if ((mid > 0 && arr[mid - 1] != K) || mid == 0)
		{
			return mid;
		}
		//当查找数与前面一个元素的值相同时,则继续向前查找
		else
		{
			end = mid - 1;
		}
	}
	//当中间值大于查找值时
	else if (arr[mid] > K)
	{
		end = mid - 1;
	}
	//当中间值小于查找值时
	else
	{
		start = mid + 1;
	}

	//递归调用
	GetFirstIndex(arr, len, K, start, end);
}

//向查找数的后面查找,获取最后一个查找数的位置
int GetLastIndex(int arr[], int len, int K, int start, int end)
{
	//递归出口,避免栈溢出
	if (start > end)
	{
		return -1;
	}

	//求中间数
	int mid = start + ((end - start) >> 1);

	//当中间值与查找数相等时
	if (arr[mid] == K)
	{
		//当查找数与后面一个元素的值不相同时,返回此时的下标
		if ((mid < len - 1 && arr[mid + 1] != K) || mid == len - 1)
		{
			return mid;
		}
		当查找数与后面一个元素的值相同时,则继续向后查找
		else
		{
			start = mid + 1;
		}
	}
	//当中间值大于查找数时
	else if (arr[mid] > K)
	{
		end = mid - 1;
	}
	//当中间值小于查找数时
	else
	{
		start = mid + 1;
	}

	//递归调用
	GetLastIndex(arr, len, K, start, end);
}

int GetTimesOfK(int arr[], int len, int K)
{
	//处理异常情况
	if (arr == NULL || len <= 0)
	{
		return -1;
	}
	int first = GetFirstIndex(arr, len, K, 0, len - 1);//获取第一个查找数的位置
	int last = GetLastIndex(arr, len, K, 0, len - 1);//获取最后一个查找数的位置
	int count = 0;//创建一个变量标记查找数在数组中出现的次数
	if (first > -1 && last > -1)
	{
		count = last - first + 1;//注意:查找数的位置差加1才是查找数在数组中出现的次数
	}
	return count;
}

int main()
{
	int arr[] = { 1, 2, 3, 3, 3, 4, 5, 6 };
	int len = sizeof(arr) / sizeof(arr[0]);
	int k = 3;
	for (int i = 0; i < len; i++)
	{
		printf("% d", arr[i]);
	}
	printf("\n");
	int ret = GetTimesOfK(arr, len, k);
	printf("%d在数组中出现的次数是% d\n",k, ret);
	system("pause");
	return 0;
}

运行结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值