分治法求數組中的衆數

先說一下題目吧,很簡單,就是給一組數組,求數組中的衆數,但是要用分治法。

看到這個題目還是比較迷的,求一個衆數,用什麼分治啊。最後參考了一下往上的各種答案,發現可以用快排的分割算法,思路如下:

首先是要運用快排的分割算法,設函數名爲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;

}

程序運行結果如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章