频率超过了50%的数首次出现的位置
题目:
现在有一数组存放int型整数,数字有重复,且有一数字出现的频率超过了50%,请找出这个数字第一次出现的位置
注:
- 如果N表示的是数组的长度
- 最有算法的复杂度为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的额外存储空间。期待更好的算法