1.题目描述
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [3,2,3]
输出: 3
示例 2:输入: [2,2,1,1,1,2,2]
输出: 2
2.解题思路
方法一:
所求为中位数,利用快速排序,在O(n)时间内找到数组中第k大的数字,这里 k = n//2。
方法二:
因为某个元素占一半以上,故采用抵消的方式,每次删除两个不同的数,抵消完毕,此元素至少还剩一个。时间复杂度为O(n)
a = [1,1,1,0,0,2,0,0,0]
2:1次
1:3次
0:5次
做法:在遍历数组的过程中,保存两个值,一个是数组中数字current,一个是出现次数count。当遍历到下一个数字时,如果这个数字跟之前保存的数字相同,则次数加1,如果不同,则次数减1。如果次数为0,则保存下一个数字并把次数设置为1,由于要找的数字出现的次数比其他所有数字出现的次数之和还要多,那么要找的数字肯定是最后一次把次数设为1时对应的数字。
3.代码实现
方法一:
class Solution(object):
def par(self,start,end,nums):
if start < end:
i = start
j = end + 1
K = nums[start]
while i < j:
i += 1
while i < end and nums[i] < K:
i += 1
j -= 1
while j > start and nums[j] > K:
j -= 1
if i < j:
nums[i], nums[j] = nums[j], nums[i]
nums[start], nums[j] = nums[j], nums[start]
return j
# 注意和原始快排的区别
else:
return end
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
# 注意要用start和end逐步缩小空间
start=0
end=len(nums)-1
k=len(nums)//2
index = self.par(start,end,nums)
while True:
if index == k:
return nums[k]
elif index < k:
start = index+1
index=self.par(start,end, nums)
else:
end=index-1
index=self.par(start,end, nums)
方法二:
#include<iostream>
using namespace std;
//size为数组A的大小
//返回数组中出现超过一半的数
int search(int *A,int size)
{
int count=0;
int current;
for(int i=0;i<size;i++)
{
if(count==0)
{
current=A[i];
count=1;
}
else
{
if(A[i]==current)
count++;
else
count--;
}
}
return current;
}
int main()
{
int A[6]={1,2,2,1,1,1};
int B[7]={1,0,1,0,0,1,1};
int C[7]={3,4,6,3,3,3,7};
cout<<search(A,6)<<" ";
cout<<search(B,7)<<" ";
cout<<search(C,7)<<" "<<endl;
int i;
cin>>i;
return 0;
}