题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
思路:第一种快速排序算法。对这个数字进行排序,排序之后位于数组中间的数组就是那个出现最多且超过数组长度一半的数字。
# -*- coding:utf-8 -*-
import random
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
# write code here
if not numbers:
return 0
length = len(numbers)
middle = length>>1
start = 0
end = length-1
index = self.Partition(numbers, length, start, end)
while (index != middle):
if index > middle:
end = index-1
index = self.Partition(numbers, length, start, end)
else:
start = index+1
index = self.Partition(numbers, length, start, end)
result = numbers[middle]
if not self.CheckMoreThanHalf(numbers, length, result):
result = 0
return result
def Partition(self, number, length, start, end):
index = random.randint(start, end)
number[index], number[end] = number[end], number[index]
small = start-1
for i in range(start,end):
if number[i] < number[end]:
small = small+1
if small!=i:
number[i], number[small] = number[small], number[i]
small+=1
number[small],number[end]=number[end],number[small]
return small
def CheckMoreThanHalf(self, numbers, length, number):
times = 0
for i in range(0, length):
if numbers[i] == number:
times+=1
isMoreThanHalf = True
if (2*times <= length):
isMoreThanHalf = False
return isMoreThanHalf
思路二:这个数字出现的次数比其他所有数字出现的次数和还要多,因此在遍历数组的时候,我们保留数组中的一个数字和它的次数。当我们遍历下一个数字的时候,如果和我们保存的数字相同则加1,不同就减1。如果次数为0,我们就保存下一个数字,并把次数设为1。我们要找的数字就是最后一次把次数设为1时对应的数字。
# -*- coding:utf-8 -*-
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
# write code here
if not numbers:
return 0
result = numbers[0]
times = 1
for i in range(1, len(numbers)):
if times == 0:
result = numbers[i]
times = 1
elif numbers[i]==result:
times+=1
else:
times-=1
if not self.CheckMoreThanHalf(numbers, len(numbers), result):
result = 0
return result
def CheckMoreThanHalf(self, numbers, length, number):
times = 0
for i in range(0, length):
if numbers[i] == number:
times+=1
isMoreThanHalf = True
if (2*times <= length):
isMoreThanHalf = False
return isMoreThanHalf