题目:
Given an array of size n, find the majority element. The majority element is dethe element that appears more than ⌊ n/2 ⌋ times.
You may assume that the array is non-empty and the majority element always exist in the array.
Example 1:Input: [3,2,3] Output: 3
Example 2:
Input: [2,2,1,1,1,2,2] Output: 2
解释:
寻找出现次数超过⌊ n/2 ⌋的数字。4
第一反应就是先排序,然后返回最中间的数(index为n//2
)即可。
但是排序比较耗时,会超时,可以用第k大的数
来做,这里k就是n//2
,好像在牛客网上(剑指offer)用python实现第k大的数的partition解法超时了,但是剑指offer上有第k大的数另一种解法,很神奇。
这个是partition解法的python代码,,其中变量middle
就是k
,超时了:
class Solution(object):
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums:
return
if nums==[nums[0]]*len(nums):
return nums[0]
def partition(nums,start,end):
i,j=start,end
pivot=nums[i]
while i<j:
while i<j and nums[j]>=pivot:
j-=1
nums[i]=nums[j]
while i<j and nums[i]<=pivot:
i+=1
nums[j]=nums[i]
nums[i]=pivot
return i
start,end=0,len(nums)-1
index=partition(nums,start,end)
middle=len(nums)>>1
while index!=middle:
if index>middle:
end=index-1
index=partition(nums,start,end)
else:
start=index+1
index=partition(nums,start,end)
return nums[index]
c++代码,没有超时,但是速度超慢,1200ms:
class Solution {
public:
int majorityElement(vector<int>& nums) {
if (nums.size()==0)
return 0;
if (count(nums.begin(),nums.end(),nums[0])==nums.size())
return nums[0];
int k=nums.size()/2;
int left=0,right=nums.size()-1;
int index=partition(nums,left,right);
//这里是二分查找
while (index!=k)
{
if(index>k)
{
right=index-1;
index=partition(nums,left,right);
}
else
{
left=index+1;
index=partition(nums,left,right);
}
}
return nums[index];
}
int partition(vector<int>&nums,int left,int right){
int pivot=nums[left];
while (left<right)
{
while(left<right &&nums[right]>=pivot)
right--;
nums[left]=nums[right];
while(left<right && nums[left]<=pivot)
left++;
nums[right]=nums[left];
}
nums[left]=pivot;
return left;
}
};
剑指offer的第二种解法,因为我们需要找的数字在数组中出现的次数大于数组的一般,所以,一定能把其他所有的数字都抵消掉,如果其他的数字不是和它抵消而是内部自己抵消,那它更能抵消掉剩下的数字,反正剩下的就是我们要求的数字了。
python代码:
class Solution(object):
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
times=1
result=nums[0]
for i in range(1,len(nums)):
if times==0:
result=nums[i]
times=1
else:
if nums[i]==result:
times+=1
else:
times-=1
return result
c++代码:
class Solution {
public:
int majorityElement(vector<int>& nums) {
int times=1;
int result=nums[0];
for (int i=1;i<nums.size();i++)
{
if (times==0)
{
result=nums[i];
times=1;
}
else
{
if(nums[i]==result)
times++;
else
times--;
}
}
return result;
}
};
总结:
剑指offer的第二种解法简直是惊为天人~!