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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

摩尔投票(包含题目讲解)

發布時間:2023/12/16 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 摩尔投票(包含题目讲解) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述一

這是 LeetCode 上的「169. 多數元素」,難度為「簡單」。

Tag : 「哈希表」、「摩爾投票」

數組中占比超過一半的元素稱之為主要元素。給你一個 整數 數組,找出其中的主要元素。

若沒有,返回 -1 。請設計時間復雜度為 n、空間復雜度為1 的解決方案。

示例 1:

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

示例 2:

輸入:nums = [2,2,1,1,1,2,2] 輸出:2

方法一:使用哈希表

class Solution {public int majorityElement(int[] nums) {int n = nums.length;Map<Integer, Integer> map = new HashMap<>();for (int x : nums) {map.put(x, map.getOrDefault(x, 0) + 1);if (map.get(x) > n / 2) return x;}return -1;} }
  • 時間復雜度:O(n)
  • 空間復雜度:O(n)

方法二:摩爾投票

摩爾投票 :在集合中尋找可能存在的多數元素,這一元素在輸入的序列重復出現并占到了序列元素的一半以上;在第一遍遍歷之后應該再進行一個遍歷以統計第一次算法遍歷的結果出現次數,確定其是否為眾數;如果一個序列中沒有占到多數的元素,那么第一次的結果就可能是無效的隨機元素。

換句話說,每次將兩個不同的元素進行「抵消」,如果最后有元素剩余,則「可能」為元素個數大于總數一半的那個。

具體的,我們定義一個變量 x 來保存那個可能為主要元素的值,cnt用來記錄該值的出現次數。然后在遍歷數組 nums過程中執行如下邏輯:

如果 cnt為0:說明之前出現過的x已經被抵消完了,更新一下x為當前值,出現次數為1:x = nums[i], cnt = 1;
如果cnt不為0:說明之前統計的x還沒被抵消完,這是根據 nums[i]與x是否相等進行計算即可:cnt += nums[i] == x ? 1 : -1。
當處理完nums之后,我們得到了一個「可能」的主要元素。注意只是可能,因為我們在處理過程中只使用了x和cnt來記錄,我們是無法確定最后剩下的x是經過多次抵消后剩余的主要元素,還是只是不存在主要元素的數組中的無效隨機元素。

因此我們需要再進行一次遍歷,檢查這個「可能」的主要元素x的出現次數是否超過總數一半。

代碼:

class Solution {public int majorityElement(int[] nums) {int n = nums.length;int x = -1, cnt = 0;for (int i : nums) {if (cnt == 0) {x = i;cnt = 1;} else {cnt += x == i ? 1 : -1;}}cnt = 0;for (int i : nums) if (x == i) cnt++;return cnt > n / 2 ? x : -1;} }

題目描述二

這是 LeetCode 上的「229. 多數元素二」,難度為「中等」。

Tag : 「哈希表」、「摩爾投票」

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

請設計時間復雜度為 n、空間復雜度為1 的解決方案。
示例 1:

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

示例 2:

輸入:nums = [1] 輸出:[1]

直接用摩爾投票

class Solution {public List<Integer> majorityElement(int[] nums) {// 根據反證法可以證明最多有兩個數大于n/3int n = nums.length;int a = -1, b = -1; // a,b為當前可能計數>n/3的數int c1 = 0, c2 = 0; // c1記錄a的數量,c2記錄b的數量for(int i : nums) {if(c1 != 0 && a == i) // a之前出現過c1++;else if(c2 != 0 && b == i) c2++;else if(c1 == 0) { // a位置沒有數c1++;a = i;} else if(c2 == 0) { // b位置沒有數c2++;b = i;} else {c1--;c2--;}}c1 = 0;c2 = 0;for(int i : nums) {if(i == a)c1++;else if(i == b)c2++;}List<Integer> ans = new ArrayList<>();if(c1 > n/3)ans.add(a);if(c2 > n/3)ans.add(b);return ans;} }

總結

以上是生活随笔為你收集整理的摩尔投票(包含题目讲解)的全部內容,希望文章能夠幫你解決所遇到的問題。

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