題目描述
數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度爲9的數組{1,2,3,2,2,2,5,4,2}。因爲數字2在數組中出現了5次,超過數組長度的一半,所以輸出2。若是不存在則輸出0。git
# -*- coding: utf-8 -*- # @Time : 2019-07-08 17:21 # @Author : Jayce Wong # @ProjectName : job # @FileName : MoreThanHalfNum.py # @Blog : https://blog.51cto.com/jayce1111 # @Github : https://github.com/SysuJayce class Solution: """ 解法1: 要尋找一個數組中出現次數大於一半的元素,那麼很明顯若是在一個有序數組中,這個元素會出如今數組中 間,也就是統計意義上的中位數。那麼經過尋找位於有序數組的中間的那個元素就能夠肯定這個中位數。 解法2: 若是一個元素出現次數大於一半,那麼這個元素的出現次數必定大於其餘全部元素的出現次數之和。 所以,若是咱們對上一次出現的元素進行統計,最後剩下的那個元素就是咱們的目標元素。 具體來講,若是當前出現的元素和以前保存的元素不同,那麼次數-1,反之+1.若是次數減到0了,那麼 保存當前新出現的元素。 """ def MoreThanHalfNum_Solution2(self, numbers): def partition(begin, stop): # 這個函數的做用就是肯定一個元素在有序數組中的正確位置,能夠用來尋找位於有序數組正中 # 間的元素 pos = begin for i in range(begin, stop): if numbers[i] < numbers[stop]: numbers[pos], numbers[i] = numbers[i], numbers[pos] pos += 1 numbers[stop], numbers[pos] = numbers[pos], numbers[stop] return pos if not numbers: return 0 mid = len(numbers) >> 1 start, end = 0, len(numbers) - 1 index = partition(start, end) while index != mid: # 若是排好序的那個元素不在正中間,那麼就根據它的位置從新肯定待排序的子數組 if index > mid: end = index - 1 else: start = index + 1 index = partition(start, end) # 注意要檢查找到的目標元素是否符合要求 count = 0 for num in numbers: if num == numbers[index]: count += 1 return numbers[index] if 2 * count > len(numbers) else 0 def MoreThanHalfNum_Solution(self, numbers): if not numbers: return 0 count = 1 ans = numbers[0] for i in range(1, len(numbers)): # 若是當前元素和保存的元素一致,那麼count+1,反之-1. if numbers[i] == ans: count += 1 else: count -= 1 # 若是count減到0,那麼用當前元素替換以前保存的元素 if count <= 0: ans = numbers[i] # 注意要檢查找到的目標元素是否符合要求 count = 0 for num in numbers: if num == ans: count += 1 return ans if count * 2 > len(numbers) else 0 def main(): nums = [1, 2, 3, 2, 2, 2, 5, 4, 2] solution = Solution() print(solution.MoreThanHalfNum_Solution(nums)) if __name__ == '__main__': main()