zoukankan      html  css  js  c++  java
  • 试用O(n)来实现求出一个无序数组的中位数

    O(n)时间实现求出一个无序数组的中位数

    对于这个问题我起初就想到了多数派问题;那么受这个问题的影响,我就先到了一种方法:就是建立一个中间判断元素。left , right 两个计数器来记录,通过遍历数组的过程中,每次都是尝试两边的元素数量尽量相同,在这个过程中,如果右边多,那么就让下个元素分配在左边,同理亦然、

    那么用代码实现就是简单的;left(程序用cx) , right(程序用cy); z  为中间计数的判断;一直到循环结束才能求出来。

    #include<iostream>
    using namespace std;
    
    int& zws(int arr[],int len);
    
    int main(){	
    	int arr[] = {1,2,7,4,9,8,100};
    	cout << "The Median of the array is : " << zws(arr,7)<<endl;
    
    	system("pause");
    	return 0;
    }
    
    int& zws(int arr[], int  len){
    	int cx = 0;
    	int cy = 0;
    	int  *z = &arr[0];
    	int i =1;
    	while((cx + cy)< (len-1)){
    		if(cx > cy){
    			if(*z  >=  arr[i]){
    				z = &arr[i];
    			}
    			cy++;
    		}else{
    			if(arr[i ] >  *z){
    				z = &arr[i];
    			}
    			cx++;
    		}
    		i++;
    		cout << "cx= "<<cx<<",   cy= "<< cy<< ",  z= "<< *z <<endl;		
    	}
    	cout << *z<< endl;  
    	return *z;
    }
    ————————————————————————————————————————

    然而,然而这个想法是错的,没错,是错的,聪明的读者,你们可以想想怎么来联立这个关系准确去实现;————————————————————————————————————————

    附录:补叙下多数派问题:

    多数派问题

    问题简述:

    假设数组v[1...n]中的每个元素v[i](1<=i<=n)对应于m个元素中的一个,这里m个元素用整数1~m表示,现在需要判断在数组v中是否有某个元素出现的次数,超过了半数。如果,v[1...n]对应于n张选票,1~m对应于m个候选人,这个问题实际上就是要判断是否有候选人的得票数严格过半(大于n/2)。

    解决思路:

    Robert S.Boyer和J Strother Moore两位牛人(就是BM算法的提出者),在《MJRTY-A Fast Majority Vote Algorithm》一文中,提出了一个巧妙算法,使得我们即使不知道m的具体情况,也可以在O(n)时间复杂度,O(1)空间复杂度内,判断是否有候选人的得票数过半。该算法在运行过程中,需要两个临时变量c和t,c记录当前可能得票数过半的候选人编号,t记录该候选人的净超出次数。对于c而言,除了可以等于1~m中的任何值之外,还有另一种状态,我们把其叫做未知状态,用于表示当前任何候选人的得票数都不可能过半(程序中可以用0,或者-1表示),t的最小值为0,程序开始运行时c为未知状态(c=0),t=0,然后按照如下方法处理投票数组v。

    • 对于v[i](1<=i<=n),如果c此时为未知状态,则c=v[i],t=1,递增i。
    • 如果c==v[i],++t,递增i。
    • 如果c!=v[i],--t,如果t==0,将c置为未知状态,递增i。
    • 所有投票处理完毕后,如果c为未知状态,则说明不存在任何候选人的得票数过半,否则重新遍历数组v,统计候选人c的实际得票总数,如果c的得票数确实过半,则c就是最终结果。
    实现程序
        int Majority(const int array[], size_t array_size)  {  
            unsigned int i;  
          
            int candidate = -1;  
            unsigned int times = 0;  
          
            for(i = 0; i < array_size; ++i)  {  
                if(candidate == -1)   {  
                    candidate = array[i];  
                    times = 1;  
                    continue;  
                }  
          
                if(candidate == array[i])   {  
                    ++times;  
                    continue;  
                }  
          
                if(--times == 0)  {  
                    candidate = -1;  
                }  
            }  
          
            if(candidate == -1)   {  
                return -1;  
            }  
          
            for(i = 0, times = 0; i < array_size; ++i)   {  
                if(array[i] == candidate)   {  
                    ++times;  
                }  
            }  
          
            if(times > array_size / 2)  {  
                return candidate;  
            }  
          
            return -1;  
        }  


  • 相关阅读:
    Eclipse修改背景颜色(豆沙绿)
    项目导入时报错:The import javax.servlet.http.HttpServletRequest cannot be resolved
    jdk1.7 环境变量配置
    Maven的安装、配置及使用入门
    tomcat端口作用
    《Maven实战》
    Maven 详解
    遍历Map的四种方法
    遍历properties文件
    题库终结
  • 原文地址:https://www.cnblogs.com/actanble/p/6713443.html
Copyright © 2011-2022 走看看