众数问题-分治策略

描述:

给定含有n个元素的多重集合S,每个元素在S中出现的次数称为该元素的重数。

多重集S中最大重数的元素称为众数。

例如S={1,2,2,2,3,5}。多重集S的众数是2,重数是3。

  • 分治策略
    1. 首先假设中间的元素是众数
    2. 然后由中间向两边遍历,直到左右都出现值不等于众数的数,记录下众数和重数
    3. 这样就将一个数组分为三部分,对左右部分执行上述步骤
    4. 注意:使用分治策略解决众数问题需要原集合有序,在原集合无序的情况下需要对其排序

使用数组与C++语言进行示范

#include <iostream>
using namespace std;
int mode = 0;	//使用全局变量,记录众数的值,初始为0
int sum = 0;	//使用全局变量,记录众数的重数,初始为0
void Merge(int *arr, int left, int middle, int right) {		//归并算法
    int *temp = new int [right-left+1];
    int i = left;
    int j = middle + 1;
    int k = 0;
    while (i <= middle && j <= right) {
        if (arr[i] <= arr[j])
            temp[k++] = arr[i++];
        else
            temp[k++] = arr[j++];
    }
    while (i <= middle)
        temp[k++] = arr[i++];
    while (j <= right)
        temp[k++] = arr[j++];
    for (i = 0; i < k; i++)
        arr[i + left] = temp[i];
    delete[] temp;
}
void MergeSort(int *arr, int left, int right) {		//归并算法
    if (left < right) {
        int middle = (left + right) / 2;
        MergeSort(arr, left, middle);
        MergeSort(arr, middle + 1, right);
        Merge(arr, left, middle, right);
    }
}
void GetMode(int *arr,int left, int middle, int right) {	//分治策略获得众数
    int tempMode = arr[middle];		//假设中间的数是众数
    int  tempSum = 1;
    int i = middle - 1;
    while (arr[i] == tempMode) {	//向左边扩展
        tempSum++;
        i--;
    }
    int j = middle + 1;
    while (arr[j] == tempMode) {	//向右边扩展
        tempSum++;
        j++;
    }
    if (tempSum > sum) {	//如果假设的众数比原来的众数的 重数 大,则替换
        sum = tempSum;
        mode = tempMode;
    }
    				/*
    				这里分别对划分出来的左右两部分进行递归
    				在进行递归前先判断左右两部分的长度是否大于 重数
    				大于重数证明划分出来的部分可能存在另外的众数
    				*/
    if(i-left+1 >sum)		
        GetMode(arr, left, (left + i) / 2, i);
    if(right - j +1> sum)
        GetMode(arr, j, (j + right) / 2, right);
}
int main()
{
    int n;
    cout << "Input n:   ";
    cin >> n;
    int* arr = new int[n];
    for (int i = 0; i < n; i++)
        cin >> arr[i];
    MergeSort(arr, 0, n - 1);		//对数组进行众数的寻找前,先对数组进行排序
    GetMode(arr, 0, n / 2, n - 1);
    cout << "mode=" << mode << ", sum=" << sum;
    return 0;
}
发布了6 篇原创文章 · 获赞 8 · 访问量 854

猜你喜欢

转载自blog.csdn.net/weixin_43853811/article/details/105230459