找出陣列中出現次數超過一半的數
面試遇到的題目,陣列中有一個數字出現的次數超過陣列長度的一半,請找出這個數字。
計數+比較
不考慮效率,採用最簡單的辦法,遍歷陣列,使用 List 的 count() 方法統計元素出現的次數:
def more_than_half_num(arr): half = len(arr) // 2 for i in arr: if arr.count(i) > half: return i return None
構造一個map,key為元素的值,value為元素出現的次數,然後遍歷map找到目標元素:
def more_than_half_num(arr): dict = {} for i in arr: if i in dict: dict[i] += 1 else: dict[i] = 1 half = len(arr) // 2 for k, v in dict.items(): if v > half: return k return None
排序+中位數
陣列排序後,如果符合條件的數存在,則一定是陣列中間那個數。可使用排序演算法對陣列進行排序,然後求排序後陣列的中間數 + 判斷中間數出現次數是否超過陣列的一半。下面以快速排序為例:
def part_sort(arr, left, right): key = right while left < right: while left < right and arr[left] <= arr[key]: left += 1 while left < right and arr[right] >= arr[key]: right -= 1 arr[left], arr[right] = arr[right], arr[left] print(arr) arr[left], arr[key] = arr[key], arr[left] return left def quick_sort(arr, left, right): if left >= right: return index = part_sort(arr, left, right) quick_sort(arr, left, index - 1) quick_sort(arr, index, right) def more_than_half_num(arr): length = len(arr) quick_sort(arr, 0, length - 1) res = arr[length // 2] if arr.count(res) > length // 2: return res else: return None
一次遍歷
陣列中有一個數字出現的次數超過陣列長度的一半,也就是說出現的次數比其他所有數字出現次數的和還要多。因此我們可以考慮在遍歷陣列的時候利用兩個輔助變數,一個記錄數字出現的次數,一個記錄數字。
- 當我們遍歷到下一個數字的時候,如果下一個數字和我們之前儲存的數字相同,則次數加1;
- 如果下一個數字和我們之前儲存的數字不同,則次數減1。
- 如果次數為零,我們需要儲存下一個數字,並把次數設為1。
def more_than_half_num(arr): res = arr[0] cnt = 1 for i in range(1, len(arr)): if arr[i] == res: cnt += 1 else: cnt -= 1 if cnt == 0: res = arr[i] cnt = 1 if arr.count(res) > len(arr)//2: return res else: return None