LeetCode---169.求眾數
阿新 • • 發佈:2018-11-10
題目來源:https://leetcode-cn.com/problems/majority-element/description/
題目描述:
演算法描述:對於該題目,可能有些人想到的就是最暴力的窮舉,但是時間複雜度為O(n2)。所以我們不用那種方法。我們可以可以使用分治演算法實現也可以用摩爾投票法。
第一種.分治演算法實現:
分治法是將整個問題化簡為一個一個的小問題去解,將陣列分成簡單的幾部分,比如講一組數分為兩部分,第一部分的眾數如果等於第二部分的眾數,則這個數就是上一層那一組的眾數,如果第一部分不等於第二部分,則遍歷這一組數,比較第一部分的眾數和第二部分的眾數哪個出現頻率高,頻率高的這個數就是這一組數的眾數。
程式碼如下:
class Solution { public int majorityElement(int[] nums) { return find(nums, 0, nums.length - 1); } public static int find(int[] nums, int begin, int end) { if (begin == end || begin + 1 == end) return nums[begin]; else { //這裡主要是為了把陣列一分為二(這裡就體現了分治演算法的思想) int mid = (begin + end) / 2; //leftNum就是一個數組中,左半部分的眾數 int leftNum = find(nums, begin, mid); //rightNum就是一個數組中,左半部分的眾數 int rightNum = find(nums, mid + 1, end); // 左右兩部分的眾數相同 則這個數是當前這個陣列的眾數 if (leftNum == rightNum) { return leftNum; }else { // 左右兩部分的眾數不相同 則這兩個數都有可能是這部分的眾數 // 那麼遍歷這個陣列 看一下哪個數字的出現頻率高,頻率高的為當前這個陣列的眾數 int countLeft = 0; int countRight = 0; for (int i = begin; i <= end; i++) if (nums[i] == leftNum) countLeft++; else if (nums[i] == rightNum) countRight++; if (countLeft > countRight) return leftNum; else return rightNum; } } } }
第二種.摩爾投票法實現:
摩爾投票法的基本思想很簡單,在每一輪投票過程中,從陣列中找出一對不同的元素,將其從陣列中刪除。這樣不斷的刪除直到無法再進行投票,如果陣列為空,則沒有任何元素出現的次數超過該陣列長度的一半。如果只存在一種元素,那麼這個元素則可能為目標元素。那麼有沒有可能出現最後有兩種或兩種以上元素呢?根據定義,這是不可能的,因為如果出現這種情況,則代表我們可以繼續一輪投票。因此,最終只能是剩下零個或一個元素。
程式碼如下:
class Solution { public int majorityElement(int[] nums) { int result = nums[0], count = 0; for (int num : nums) { if (count == 0) { result = num; count++; } else { if (result == num) { count++; } else { count--; } } } return result; } }