日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Boyer-Moore 投票算法

發布時間:2023/12/13 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Boyer-Moore 投票算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 算法概述
  • 題目
    • k=2
      • 思路
      • 代碼
      • 復雜度分析
    • k=3
      • 思路
      • 代碼
      • 復雜度分析


算法概述

摩爾投票算法經常用于求眾數的題目,即,求 出現次數>n/k 的數,可以證明,出現次數超過 n/k 的數最多只有 k-1 個。否則必然違背「數總共只有 n 個」或者「當前統計的是出現次數超過 n/k 的數」的前提條件。

  • 我們可以設定 k-1 個變量來記錄最終結果。
  • 以 k-1=3 為例,所求結果設為 k1、k2,用兩個變量 n1、n2 分別記錄 k1、k2 的出現次數。遍歷給定的數組 nums,設 當前便利的到的元素為 nums[i] ,分情況處理:
  • n1==0,此時需要更換 k1 ,k1=nums[i]。
  • n2==0,此時需要更換 k2 ,k2=nums[i]。
  • n1>0 且 nums[i]==k1,n1++。
  • n2>0 且 nums[i]==k2,n2++。
  • 不屬于以上四種情況則表明,n1>0 且 n2>0 且 nums[i]!=k1 且 nums[i]!=k1 ,即 nums[i] 不等于 k1 也不等于 k2,同時 k1、k2 的出現次數大于 0,因此只需將兩者的出現次數 -1 即可:n1--、n2-- 。

題目

k=2

數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。

你可以假設數組是非空的,并且給定的數組總是存在多數元素。

示例:

輸入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
輸出: 2


思路

用變量 x 代表要求的最終結果,也就是數組中的眾數。
用 sum 代表票數和。

推論一: 若記 眾數 的票數為 +1,非眾數 的票數為 -1,則一定有所有數字的 票數和 > 0。
推論二: 若數組的前 a 個數字的 票數和 = 0 ,則 數組剩余 (n-a) 個數字的 票數和一定仍 > 0 ,即后 (n-a) 個數字的 眾數仍為 x 。

第一條顯而易見,題目講的很清楚,最終要求的數出現的次數超過這組數字個數的二分之一,因此眾數個數大于非眾數。

第二條推論中,票數和=0 的情況代表著 這一段中眾數個數與非眾數個數相等,因此成立。

而我們不斷的割掉推論二中的 票數和=0的一段 ,具體做法是(上圖中黑字x):每當 sum=0 時,此時將 x 更新為 下一段數字中的首元素,最終剩下的一段中的 x 即為我們所求的最終結果。


代碼

class Solution { public:int majorityElement(vector<int>& nums) {int sum = 0, x;for(int i = 0; i < nums.size(); i++){if(!sum) x = nums[i];sum += nums[i]==x?1:-1;}//加入了驗證最終x是否大于數組長度一半的操作//當然在本題中是肯定的int count = 0;for(int& num:nums)if(num==x) count++;return count>nums.size()/2?x:-1;//當無眾數時返回-1} };

復雜度分析

  • 空間復雜度O(N):遍歷數組。
  • 時間復雜度O(1):未開辟新空間。

k=3

給定一個大小為 n 的整數數組,找出其中所有出現超過 ? n/3 ? 次的元素。(LC題目鏈接)

示例:

輸入: [3,2,3]
輸出: [3]


思路

如果兩個人的票數都超過了三分之一,剩余的票就不到三分之一了,因此最多有兩個超過 n/3 的元素。


代碼

class Solution { public:vector<int> majorityElement(vector<int>& nums) {// 如果兩個人的票數都超過了三分之一,剩余的票就不到三分之一了// 因此最多有兩個超過n/3的元素,摩爾投票法vector<int> v;int n1 = 0, n2 = 0, a = 0, b = 0;for(auto i:nums){if(n1>0 && i==a) n1++;else if(n2>0 && i==b) n2++;else if(n1==0){a=i;n1=1;}else if(n2==0){b=i;n2=1;}else{n1--;n2--;}//cout << a << " " << n1 << " " << b << " " << n2 << endl;}int cnt1 = 0, cnt2 = 0;for(auto i:nums){if(n1>0 && i==a) cnt1++;if(n2>0 && i==b) cnt2++;}if(cnt1>nums.size()/3) v.push_back(a);if(cnt2>nums.size()/3) v.push_back(b);return v;} };

復雜度分析

  • 時間復雜度:O(n):其中 n 為數組的長度。
  • 空間復雜度:O(1):只需要常數個元素用來存儲關鍵元素和統計次數即可。

總結

以上是生活随笔為你收集整理的Boyer-Moore 投票算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。