題目:
數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。
直接的思路就是先給數組進行排序,然後就能很容易地統計出每個數字出現的次數。
但是這種思路並沒有考慮到數組的特性:數組中有一個數字出現的次數超過了數組長度的一半。如果將這個數組排序,那麼排序之後位於數組中間的數字一定就是那個出現次數超過數組長度一半的數字,即中位數。
bool g_bInputInvalid=false;
//判斷輸入的數組是否無效
bool CheckInvalidArray(int* numbers,int length)
{
g_bInputInvalid=false;
if(numbers==NULL || length<=0)
g_bInputInvalid=true;
return g_bInputInvalid;
}
//判斷數組中是否有滿足要求的元素存在
bool CheckMoreThanHalf(int* numbers,int length,int number)
{
int times=0;
for(int i=0;i<length;++i)
{
if(numbers[i]=number)
times++;
}
bool isMoreThanHalf=true;
if(times*2<=length)
{
g_bInputInvalid=true;
isMoreThanHalf=false;
}
return isMoreThanHalf;
}
//找到元素
int MoreThanHalfNum(int* numbers,int length)
{
if(CheckInvalidArray(numbers,length))
return 0;
int middle=length>>1;
int start=0;
int end=length-1;
int index=Partition(numbers,length,start,end);
while(index!=middle)
{
if(index>middle)
{
end=index-1;
//Partiton:快速排序
index=Partition(numbers,length,start,end);
}
else
{
start=index+1;
index=Partition(numbers,length,start,end);
}
}
int result=numbers[middle];
if(!CheckMoreThanHalf(numbers,lengh,result))
result=0;
return result;
}
另一種思路:
數組中有一個數字出現次數超過數組長度的一半,也就是它出現的次數比其他所有數字出現的次數的和還要多。
可以考慮在遍歷數組的時候保存兩個值:一個數組中的數字,一個次數。
當我們遍歷到下一個數字的時候,如果下一個數字和我們之前保存的數字相同,則次數加1;如果下一個數字和我們之前保存的數字不同,則次數減1.如果次數爲0,則我們需要保存下一個數字,並把次數設爲1。由於我們要找的數字出現的次數比其他數字出現的次數之和還要多,因此要找的數字應該是最後一次把次數設爲1的數字。
int MoreThanHalfNum(int* numbers,int length)
{
if(CheckInvalidArray(numbers,length);
return 0;
int result=numbers[0];
int times=1;
for(int i=1;i<length;i++)
{
if(times==0)
{
result=numbers[i];
times=1;
}
else if(numbers[i]==result)
times++;
else
times--;
}
if(!CheckMoreThanHalf(numbers,length,result);
result=0;
return result;
}