题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。
方法一:
首先把这个数组排序,那么排序之后位于数组中间的数字一定就是那个出现次数超过数组长度一半的数字。
时间复杂度为 O(nlogn)
C++代码实现:
#include<iostream>
#include<vector>
using namespace std;
int MoreThanHalfNum_Solution(vector<int>&arr)
{
int len = arr.size();
int count = 0;
sort(arr.begin(), arr.end());
int num = arr[len / 2];
return num;
for(int i = 0; i < len; i++)
{
if (num == arr[i])
{
count++;
}
}
if (count>len / 2)
{
return num;
}
else
{
return 0;
}
}
方法二:
如果一个数出现的次数超过数组一半的长度,那么就是说出现的次数比其他所有数字出现的次数还要多。因此我们可以考虑保存2个值,一个是数组中的一个数,一个是数出现的次数。当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加1,如果不同则次数减1。如果次数为0了这保存当前遍历到的数,并把次数设为1。遍历完整个数组之后,返回当前保存的数字,即是我们要找的数字。
时间复杂度为O(n)
C++代码实现:
#include<iostream>
#include<vector>
using namespace std;
int MoreThanHalfNum(vector<int>& nums)
{
int len = nums.size();
int result = nums[0];
int count=1;
for(int i=1;i<len;i++)
{
if(count == 0)
{
result=nums[i];
count++;
}
if(nums[i]==result)
{
count++;
}
else
{
count--;
}
}
return result;
}
方法三:
使用栈来实现,如果栈为空或者栈顶元素等于数组中的元素时入栈,然后每次入栈时和栈顶的数比较,当数组中的数与栈顶的数不相等时就出栈。最后栈顶的元素就是数组中出现次数超过数组长度一半的数字。
C++代码实现:
时间复杂度O(n)
int MoreThanHalfNum1(vector<int> &nums)
{
stack<int> st;
int len = nums.size();
for (int i = 0; i < len; i++)
{
if (st.empty() || st.top() == nums[i])
{
st.push(nums[i]);
}
else
{
st.pop();
}
}
if (st.empty())
{
return 0;
}
else
{
int count = 0;
for (int i = 0; i < len; i++)
{
if (nums[i] == st.top())
{
count++;
}
}
if (count>len / 2)
{
return st.top();
}
else
{
return 0;
}
}
}