分治法求数组中的众数

先说一下题目吧,很简单,就是给一组数组,求数组中的众数,但是要用分治法。

看到这个题目还是比较迷的,求一个众数,用什么分治啊。最后参考了一下往上的各种答案,发现可以用快排的分割算法,思路如下:

首先是要运用快排的分割算法,设函数名为quick,重复次数设置为n,众数设为mode,数组长度即为length.

  • 选取中间的值作为基准值来进行快排分割,这样做可以尽量去避免重复的计算。
  • 记k为快排分割的返回值,即为基准值的最终位置,同时在进行快排分割函数的时候需要记录基准值的重复次数,如果大于n,那么将mode更新为基准值,同时更新n.
  • 如果k-left>=n,那么左边的数可能存在众数,对数组(left,k-1)进行快排分割
  • 如果right-k>=n,那么右边的数可能存在众数,对数组(k+1,right)进行快排分割
  • 递归的去重复上述步骤。

C++实现的代码如下:

#include<iostream>
using namespace std;
//全局变量存储重数
int n = 0;
//全局变量存储众数
int mode = INT_MIN;
void Swap(int* arr, int num1, int num2)
{
	int temp = arr[num1];
	arr[num1] = arr[num2];
	arr[num2] = temp;
}
//快排分割函数
int quick(int* arr, int low, int high)
{
	int nTemp = 1;
	//从中间选取基准
	int mid = (low + high) / 2;
	if (arr[low] > arr[mid])
		Swap(arr, low, mid);
	if (arr[low] > arr[high])
		Swap(arr, low, high);
	if (arr[mid] > arr[high])
		Swap(arr, mid, high);
	Swap(arr, low, mid);
	int temp = arr[low];
	while (low < high)
	{
		while (low < high )
		{
			if (temp == arr[high])
				++nTemp;
			if (temp > arr[high])
				break;
			--high;
		}
		if (low < high)
		{
			arr[low] = arr[high];
			++low;
		}
		while (low < high )
		{
			if (temp == arr[low])
				++nTemp;
			if (temp < arr[low])
				break;
			++low;
		}
		if (low < high)
		{
			arr[high] = arr[low];
			--high;
		}
	}
	arr[high] = temp;
	if (nTemp > n)
	{
		n = nTemp;
		mode = temp;
	}
	return low;
}
void getMode(int* arr, int start, int end)
{
	if (start >= end)
		return;
	int k = quick(arr, start, end);
	if ((k - start) >= n)
		getMode(arr, start, k - 1);
	if ((end - k) >= n)
		getMode(arr, k + 1, end);
}
int main()
{
	int arr[] = { 3,4,1,2,2,2,3,3,5 };
	getMode(arr, 0, sizeof(arr) / sizeof(arr[0]) - 1);
	cout << "众数为:" << mode << "    重数为:" << n << endl;

}

程序运行结果如下:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值