频率超过了50%的数首次出现的位置

题目:

现在有一数组存放int型整数,数字有重复,且有一数字出现的频率超过了50%,请找出这个数字第一次出现的位置

注:

  1. 如果N表示的是数组的长度
  2. 最有算法的复杂度为N

 

解答:

//分析: 某数字频率超过了50%,可以肯定该数字为中位数(如果排好序,第N/2个数)

//解答分两个过程:

//1: 求中位数,和求最大最小值一样有O(N)算法

//2: 求这个中位数的首次出现位置 O(N)

#include "stdafx.h"

 

int partion(int *A,int low,int high)

{

int temp =A[low];

while(low<high)

{

while(A[high]>=temp && low<high)

high--;

A[low]=A[high];                    

while(A[low]<=temp && low<high)

low++;

A[high]=A[low];

}

A[low]=temp;

return low;

}

 

//获取第K小的数

int getK(int *A,int low,int high,int k)

{

int p = partion(A,low,high);

if(low+k-1==p)// p正好是low和high区间的第k个数的下标

{

return A[p];

}

else if(low+k-1<p) //第K个数落在low和p-1区间 ,寻找这个区间的第K个大数

{

return getK(A,low,p-1,k);

}

else if(low+k-1>p) //第K个数落在p+1和high区间 ,寻找这个区间的第k-1-p+low个大数

{

return getK(A,p+1,high,k-1-p+low);

}

}

 

 

int _tmain(int argc, _TCHAR* argv[])

{

//test data

const int len = 10;

int *A= new int[len];

A[0]=9;

A[1]=2;

A[2]=6;

A[3]=9;

A[4]=3;

A[5]=3;

A[6]=7;

A[7]=3;

A[8]=3;

A[9]=3;

 

//操作过程中改变数组内容了 先备份

int *tempArray = new int [len];

int i;

for(i=0;i<len;i++)

tempArray[i]=A[i];

 

//获取中位数

int data = getK(A,0,len-1,len/2);

//在tempArray中获取中位数首次出现位置

for(i=0;i<len && tempArray[i]!=data;i++);

 

int index = i;

 

return 0;

}

 

O(N)的时间复杂度 还使用了N的额外存储空间。期待更好的算法

posted on 2011-12-01 15:39  NN小白  阅读(284)  评论(0编辑  收藏  举报