這道題有 5 種方法,8 種實現,詳細分析能夠看<u>花花醬</u>的 YouTube 專欄。java
[TOC]python
給定一個大小爲 n 的數組,找到其中的衆數。衆數是指在數組中出現次數大於 ⌊ n/2 ⌋
的元素。算法
你能夠假設數組是非空的,而且給定的數組老是存在衆數。數組
示例 1:ide
輸入: [3,2,3] 輸出: 3
示例 2:spa
輸入: [2,2,1,1,1,2,2] 輸出: 2
遍歷數組中的每一個元素,統計該元素出現的次數(嵌套遍歷),若是該元素出現的次數 $> \left \lfloor n/2 \right \rfloor$,則該元素就是數組的衆數。code
class Solution { public int majorityElement(int[] nums) { int majorityCount = nums.length / 2; for (int num1 : nums) { int count = 0; for (int num2 : nums) { if (num2 == num1) { ++count; } } if (count > majorityCount) { return num1; } } throw new IllegalArgumentException("The array does not contain a majority element!"); } }
class Solution: def majorityElement(self, nums): """ :type nums: List[int] :rtype: int """ majority_count = len(nums) // 2 for num1 in nums: count = sum(1 for num2 in nums if num2 == num1) if count > majority_count: return num1
for
循環,所以總的時間複雜度是 $O(n^2)$ 的利用哈希表記錄數組中元素出現的次數,因爲哈希表的插入操做的時間複雜度是 $O(1)$ 的,因此遍歷整個數組統計出現次數的操做的時間複雜度是 $O(n)$ 的。接着,再遍歷一遍哈希表,取出衆數。blog
class Solution { public int majorityElement(int[] nums) { Map<Integer, Integer> counts = new HashMap<>(); for (int num : nums) { if (counts.containsKey(num)) { counts.replace(num, counts.get(num) + 1); } else { counts.put(num, 1); } } Map.Entry<Integer, Integer> majorityEntry = null; for (Map.Entry<Integer, Integer> entry : counts.entrySet()) { if (majorityEntry == null || entry.getValue() > majorityEntry.getValue()) { majorityEntry = entry; } } return majorityEntry.getKey(); } }
class Solution: def majorityElement(self, nums): """ :type nums: List[int] :rtype: int """ counts = dict() for num in nums: counts[num] = counts.get(num, 0) + 1 return max(counts, key=counts.get)
將數組按照順序(遞增或者遞減)排列好後,索引爲 $\left \lfloor n/2 \right \rfloor$ 的元素就是數組的衆數。排序
class Solution { public int majorityElement(int[] nums) { Arrays.sort(nums); return nums[nums.length / 2]; } }
class Solution: def majorityElement(self, nums): """ :type nums: List[int] :rtype: int """ return sorted(nums)[len(nums) // 2]
多數投票算法通常用於尋找一個序列的多數元素(只須要線性時間和常數空間),是一種典型的流式算法(streaming algorithm)。可是,通常來講,該算法沒法找到一個序列的衆數(mode),除非衆數出現的次數大於 $\lfloor n/2 \rfloor$ 次。多數投票算法的思想是這樣:統計一個序列中的全部元素,將多數元素記爲 $+1$,其他的元素記爲 $-1$,那麼最後的和必定是正的。具體地,該算法會維護兩個變量,一個用於記錄序列中的元素,記爲 m
,一個做爲計數器,記爲 count
。遍歷數組中的每一個元素,若是當前的 count
爲 0,則將當前元素保存在 m
中,並設 count
爲1;若是 count
不爲0,則判斷當前元素與 m
是否相等,相等則 count
加一,不等則 count
減一。遍歷結束,變量 m
就是咱們尋找的多數元素。索引
class Solution { public int majorityElement(int[] nums) { int me = nums[0], count = 1; for (int i = 1; i < nums.length; ++i) { if (count == 0) { me = nums[i]; count = 1; } else if (me == nums[i]) { ++count; } else { --count; } } return me; } }
class Solution: def majorityElement(self, nums): """ :type nums: List[int] :rtype: int """ me, count = 0, 0 for num in nums: if count == 0: me, count = num, 1 elif me == num: count += 1 else: count -= 1 return me