1.题目
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
2.Code
方法1:排序,数组排序后数组中只出现的数字次数多于数组长度必然会包含中位数,之后遍历这个数组统计次数即可
排序的时间复杂度要高点O(n*logn)
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> arr) {
int size = arr.size();
if(size <= 0) return 0;
sort(arr.begin(),arr.end());
int res = arr[size/2];
int count = 0;
for (int i = 0; i < size; ++i)
{
if(arr[i] == res){
count++;
}
}
if(count <= size/2){
return 0;
}
return res;
}
};
方法2:遍历数组是保存2个值:res保存数组值,count保存这个数的出现次数。初始值设定为a[0],之后遍历数组,相等则+1,否则-1,当count值为0时此时a[i]处设定为1。res
统计的数字至少是长度的一半,所以最后一次将count置为1的就是答案,需要判断是否长度符合
时间复杂度O(n)
class Solution {
public:
//判断这个数字是否出现次数超过一半
bool Judge(vector<int>& a, int ans){
int size = a.size();
int count = 0;
for(int i = 0; i < size; ++i){
if(a[i] == ans){
++count;
}
}
if(count <= (size/2)){
return false;
}
return true;
}
int MoreThanHalfNum_Solution(vector<int> a) {
int size = a.size();
if(size <= 0) return 0;
int res = a[0];
int count = 1;
for(int i = 1; i < size; ++i){
if(count == 0){
res = a[i];
count = 1;
}
else if(a[i] == res){
count++;
}
else{
count--;
}
}
if(!Judge(a, res)){
res = 0;
}
return res;
}
};
方法3:基于快排中partition的过程去解决中位数
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> arr) {
int len = arr.size();
if(len <= 0) return 0;
int left = 0,
int right = len - 1;
int mid = len / 2;
int index = Partition(arr, left, right);
while(index != mid){
if(index > mid){
right = index - 1;
index = Partition(arr, left, right);
}
else{
left = index + 1;
index = Partition(arr, left, right);
}
}
int res = arr[mid];
if(!CheckMoreHalf(arr, res)){
res = 0;
}
return res;
}
int Partition(vector<int>& arr, int left, int right){
int pivot = arr[right];
int less = left - 1;
int more = right;
int pos = left;
while(pos < more){
if(arr[pos] < pivot){
swap(arr[++less],arr[pos++]);
}
else if(arr[pos] > pivot){
swap(arr[--more],arr[pos]);
}else{
++pos;
}
}
swap(arr[more],arr[right]);
return less+1;
}
bool CheckMoreHalf(vector<int>& arr, int result){
int count = 0;
int size = arr.size();
for(int i = 0; i < szie; ++i){
if(arr[i] == result){
++count;
}
}
if(count <= size/2){
return false;
}
return true;
}
};