1. 程式人生 > 其它 >Boyer-Moore投票演算法找多數元素

Boyer-Moore投票演算法找多數元素

技術標籤:演算法類演算法javahashmap

  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。

  3.最後返回candidate。
image.png

程式碼

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;
    }
}