题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。没有找到输出为0。
解法1:可以直接对其该数组进行排序,排序后,再统计每个数字出现的次数,得到出现次数最多数和次数需要时间为O(nlogn)
int MoreThanHalfNum_Solution(vector<int> numbers) {
int size=numbers.size();
if(size==0)
return 0;
if(size==1)
return numbers[0];
sort(numbers.begin(),numbers.end());///对numbers进行字典排序
//vector<int>::iterator it;
int index=(size-1)/2;
bool isMore;
isMore=IsMoreThanHalf(numbers,numbers[index],size);//返回true or false
if(isMore)
return numbers[index];
else
return 0;
}
bool IsMoreThanHalf(vector<int> numbers,int num,int length)
{
int num1=0;
for(int i=0;i<length;i++)
{
if(numbers[i]==num)
num1++;
}
if(num1>length/2)
return true;
else
return false;
}
int size=numbers.size();
if(size==0)
return 0;
if(size==1)
return numbers[0];
sort(numbers.begin(),numbers.end());///对numbers进行字典排序
//vector<int>::iterator it;
int index=(size-1)/2;
bool isMore;
isMore=IsMoreThanHalf(numbers,numbers[index],size);//返回true or false
if(isMore)
return numbers[index];
else
return 0;
}
bool IsMoreThanHalf(vector<int> numbers,int num,int length)
{
int num1=0;
for(int i=0;i<length;i++)
{
if(numbers[i]==num)
num1++;
}
if(num1>length/2)
return true;
else
return false;
}
解法2:
其中若存在有一个数字出现的次数超过该数组长度的一半,则该数字必在排序后数组的中位数处,即求一个k个数组中第k/2大数字,则存在O(n)时间复杂度算法使得求出第k/2,利用快速排序的思想来去求
int MoreThanHalfNum_Solution(vector<int> numbers) {
int size=numbers.size();
if(size==0)
return 0;
if(size==1)
return numbers[0];
// sort(numbers.begin(),numbers.end());///对numbers进行字典排序
//vector<int>::iterator it;
// int index=(size-1)/2;
int index=GetMiddle(numbers);
bool isMore;
isMore=IsMoreThanHalf(numbers,index,size);
if(isMore)
return index;
else
return 0;
}
bool IsMoreThanHalf(vector<int> numbers,int num,int length)
{
int num1=0;
for(int i=0;i<length;i++)
{
if(numbers[i]==num)
num1++;
}
if(num1>length/2)
return true;
else
return false;
}
//快排
int particition(vector<int> &numbers,int begin,int end)
{
int i=begin;
int j=end;
int temp=numbers[begin];
// int temp1
while(i<j)
{
while(i<j&&numbers[j]>temp)j--;
if(i<j)
{
numbers[i]=numbers[j];
i++;
}
while(i<j&&numbers[i]<temp)i++;
if(i<j)
{
numbers[j]=numbers[i];
j--;
}
}
numbers[i]=temp;
return temp;/找到某个数字存在的位置
}
//找到第k大的数字
int GetMiddle(vector<int> &numbers)
{
int begin=0;
int end=numbers.size()-1;
int middle=numbers.size()>>1;
int index=particition(numbers,begin,end);
while(index!=middle)
{
if(index<middle)
{
begin=index+1;
index=particition(numbers,begin,end);
}
else
{
end=index-1;
index=particition(numbers,begin,end);
}
}
return numbers[middle];
}
int size=numbers.size();
if(size==0)
return 0;
if(size==1)
return numbers[0];
// sort(numbers.begin(),numbers.end());///对numbers进行字典排序
//vector<int>::iterator it;
// int index=(size-1)/2;
int index=GetMiddle(numbers);
bool isMore;
isMore=IsMoreThanHalf(numbers,index,size);
if(isMore)
return index;
else
return 0;
}
bool IsMoreThanHalf(vector<int> numbers,int num,int length)
{
int num1=0;
for(int i=0;i<length;i++)
{
if(numbers[i]==num)
num1++;
}
if(num1>length/2)
return true;
else
return false;
}
//快排
int particition(vector<int> &numbers,int begin,int end)
{
int i=begin;
int j=end;
int temp=numbers[begin];
// int temp1
while(i<j)
{
while(i<j&&numbers[j]>temp)j--;
if(i<j)
{
numbers[i]=numbers[j];
i++;
}
while(i<j&&numbers[i]<temp)i++;
if(i<j)
{
numbers[j]=numbers[i];
j--;
}
}
numbers[i]=temp;
return temp;/找到某个数字存在的位置
}
//找到第k大的数字
int GetMiddle(vector<int> &numbers)
{
int begin=0;
int end=numbers.size()-1;
int middle=numbers.size()>>1;
int index=particition(numbers,begin,end);
while(index!=middle)
{
if(index<middle)
{
begin=index+1;
index=particition(numbers,begin,end);
}
else
{
end=index-1;
index=particition(numbers,begin,end);
}
}
return numbers[middle];
}
该程序未能AC并且超时,主要原因是其在partition时未能进行随机划分,即对于那个标准数应该随机给出
即在partition函数中给出如下,则不会超时,并能AC
int particition(vector<int> &numbers,int begin,int end)
{
int i=begin;
int j=end;
int temp=numbers[begin];
srand((unsigned)time(NULL));
int ran=random()%(end-begin)+begin;
temp=numbers[ran];
numbers[ran]=numbers[begin];
numbers[begin]=temp;
// int ran=random(end)
// int temp1
while(i<j)
{
while(i<j&&numbers[j]>temp)j--;
if(i<j)
{
numbers[i]=numbers[j];
i++;
}
while(i<j&&numbers[i]<temp)i++;
if(i<j)
{
numbers[j]=numbers[i];
j--;
}
}
numbers[i]=temp;
return temp;/找到某个数字存在的位置
}
{
int i=begin;
int j=end;
int temp=numbers[begin];
srand((unsigned)time(NULL));
int ran=random()%(end-begin)+begin;
temp=numbers[ran];
numbers[ran]=numbers[begin];
numbers[begin]=temp;
// int ran=random(end)
// int temp1
while(i<j)
{
while(i<j&&numbers[j]>temp)j--;
if(i<j)
{
numbers[i]=numbers[j];
i++;
}
while(i<j&&numbers[i]<temp)i++;
if(i<j)
{
numbers[j]=numbers[i];
j--;
}
}
numbers[i]=temp;
return temp;/找到某个数字存在的位置
}
解法3:根据这个题目特性,存在一个数字出现的次数超过数组长度的一半,则该数出现的次数必定比其他数出现的次数之和还多,则可以用两个变量来存该数字result和该数字“净出现”次数times,初始时出现的次数为0,则对遍历的该数字赋给result,次数times自加。如果times不为0并且遍历的该数与result相等,则times自加,不相等则times自减。若存在某个数字出现的次数超过数组长度的一半,最后得到的result必是该数。
class Solution{
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int size=numbers.size();
if(size==0)
return 0;
if(size==1)
return numbers[0];
///即有一个数字出现的次数,比其他数出现的次数还要多,维持2个变量
///1个变量保存数组中的值,1个变量保存该数出现的次数
int result,times=0;
for(int i=0;i<size;i++)
{
if(times==0)///次数为0 时,重新赋值
{
result=numbers[i];
times++;
}
else if(result==numbers[i])///当遍历到的值与保存的值相等时,次数加1
times++;
else ///当遍历到的值与保存的值不相等时,次数减1
times--;
}
bool isMore;
isMore=IsMoreThanHalf(numbers,result,size);
if(isMore)
return result;
else
return 0;
}
bool IsMoreThanHalf(vector<int> numbers,int num,int length)
{
int num1=0;
for(int i=0;i<length;i++)
{
if(numbers[i]==num)
num1++;
}
if(num1>length/2)
return true;
else
return false;
}
};
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int size=numbers.size();
if(size==0)
return 0;
if(size==1)
return numbers[0];
///即有一个数字出现的次数,比其他数出现的次数还要多,维持2个变量
///1个变量保存数组中的值,1个变量保存该数出现的次数
int result,times=0;
for(int i=0;i<size;i++)
{
if(times==0)///次数为0 时,重新赋值
{
result=numbers[i];
times++;
}
else if(result==numbers[i])///当遍历到的值与保存的值相等时,次数加1
times++;
else ///当遍历到的值与保存的值不相等时,次数减1
times--;
}
bool isMore;
isMore=IsMoreThanHalf(numbers,result,size);
if(isMore)
return result;
else
return 0;
}
bool IsMoreThanHalf(vector<int> numbers,int num,int length)
{
int num1=0;
for(int i=0;i<length;i++)
{
if(numbers[i]==num)
num1++;
}
if(num1>length/2)
return true;
else
return false;
}
};