Boyer-Moore投票演算法找多數元素
Boyer-Moore可能很多同學並不瞭解,但你如果百度一下就會發現這是位牛人、大佬,他在1977年提出的BM(Boyer-Moore)演算法被認為是最高效的字串搜尋演算法, 一般情況下,比KMP演算法快3-5倍,因此文字編輯器中的搜尋匹配功能,多使用該演算法實現。
力扣第169題: 多數元素
給定一個大小為 n 的陣列,找到其中的多數元素。多數元素是指在陣列中出現次數 大於 ⌊ n/2 ⌋ 的元素。
你可以假設陣列是非空的,並且給定的陣列總是存在多數元素。
示例 1:
輸入:[3,2,3]
輸出:3
示例 2:
輸入:[2, 2,1,1,1,2,2]
輸出:2
進階:
嘗試設計時間複雜度為 O(n)、空間複雜度為 O(1) 的演算法解決此問題。
解法一:輔助HashMap法
解題思路
使用長度為n/2的HashMap統計所有數字出現的次數,當某個數字出現的次數大於n/2時,直接返回,具體流程為:
1.定義長度為n/2的HashMap,以nums[i]為key,以出現的次數為value;
2.遍歷陣列nums,每次遍歷操作為:
1)若map的key中包含nums[i]則令該key對應的value加1,若加1後大於n/2則直接返回nums[i];
2)若不包含則為nums[i]新增新的對映。
程式碼
class Solution { public int majorityElement(int[] nums) { int len=nums.length; HashMap<Integer,Integer>map=new HashMap<Integer,Integer>(len/2); for(int i=0;i<len;i++){ if(map.containsKey(nums[i])){ int temp=map.get(nums[i])+1; if(temp>len/2)return nums[i]; map.put(nums[i],temp); }else{ map.put(nums[i],1); } } return nums[0]; }
這種解法能夠找出要求的數字,但所需空間複雜度為O(n),不符合題目的要求,因此我們使用第二種解法。
解法二:Boyer-Moore投票演算法
解題思路
Boyer-Moore投票演算法利用了一種很巧妙的方法,具體流程為:
1.定義一個輔助變數candidate用於儲存候選數字,count用於儲存候選數字出現的次數;
2.遍歷陣列,每次遍歷的操作為:
1)若count為0,則更新candidate為當前遍歷到的nums[i],並使count加1;
2)若count不為0,則將candidate與當前遍歷到的nums[i]進行比較,若相等則count加1,若不等則count減1。
程式碼
class Solution {
public int majorityElement(int[] nums) {
int count=0;
int candidate=0;
for(int i=0;i<nums.length;i++)
{
if(count==0)
{
candidate=nums[i];
count++;
}else
{
if(nums[i]==candidate)
{
count++;
}else
{
count--;
}
}
}
return candidate;
}
}